Mengukur performa dengan web-vitals.js, Google Analytics, dan BigQuery

1. Sebelum memulai

Yang akan Anda lakukan

Dalam codelab ini, Anda akan:

  • Menautkan Properti Google Analytics 4 ke BigQuery.
  • Menambahkan library web-vitals ke halaman web.
  • Menyiapkan dan mengirim data web-vitals ke Google Analytics.
  • Membuat kueri data Data Web Inti di BigQuery.
  • Membuat dasbor di Google Data Studio untuk memvisualisasikan data Data Web Inti.

Yang akan Anda butuhkan

  • Akun Google Analytics dengan properti GA4.
  • Akun Google Cloud.
  • Browser web berbasis Chromium, seperti Google Chrome atau Microsoft Edge. (Untuk mengetahui informasi lengkap alasan Anda memerlukan browser web berbasis Chromium, lihat Dukungan Browser.)
  • Editor teks pilihan Anda, seperti Sublime Text atau Visual Studio Code.
  • Tempat untuk menghosting halaman pengujian Anda guna mengetahui cara kerja library web-vitals. (Anda dapat menggunakan server lokal untuk mengirimkan halaman web statis, atau menghosting halaman pengujian di GitHub.)
  • Situs publik tempat Anda dapat men-deploy kode analisis. (Dengan menyertakan kode Anda ke tahap produksi, contoh BigQuery dan Data Studio di akhir Codelab ini menjadi lebih mudah dipahami.)
  • Pengetahuan tentang HTML, CSS, JavaScript, dan Chrome DevTools.

Sebelum memulai

Pertama, tautkan Google Analytics 4 ke BigQuery, untuk memastikan Anda dapat langsung mulai menganalisis performa setelah kode dipublikasikan.

Ikuti langkah-langkah di Pusat Bantuan Google Analytics untuk menautkan properti GA4 Anda ke BigQuery.

Setelah properti Google Analytics siap mengekspor data peristiwa ke BigQuery, integrasikan library web-vitals di situs Anda.

2. Menambahkan library web-vitals dan gtag ke halaman web

Pertama, tambahkan library web-vitals ke halaman web.

  1. Buka template halaman tempat Anda ingin menambahkan library web-vitals. Untuk contoh ini, kita akan menggunakan halaman sederhana:

basic.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Web Vitals Test</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <p><img style="max-width: 360px" src="https://placekitten.com/g/3840/2160" alt="Kitten" /></p>
  <p>Text below image</p>
</body>
</html>
  1. Tempel kode sumber ke dalam file kosong di editor teks.
  2. Simpan file secara lokal sebagai basic.html.
  3. Salin skrip modul ini, lalu tempelkan tepat sebelum tag </body> penutup. Skrip ini memuat library web-vitals dari jaringan penayangan konten (CDN).

basic.html

<script type="module">
  import {getCLS, getFID, getLCP} from 'https://unpkg.com/web-vitals?module';

  getCLS(console.log);
  getFID(console.log);
  getLCP(console.log);
</script>

Kode yang dihasilkan akan terlihat seperti ini.

basic.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Web Vitals Test</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <p><img style="max-width: 360px" src="https://placekitten.com/g/3840/2160" alt="Kitten" /></p>
  <p>Text below image</p>

<script type="module">
  import {getCLS, getFID, getLCP} from 'https://unpkg.com/web-vitals?module';

  getCLS(console.log);
  getFID(console.log);
  getLCP(console.log);
</script>
</body>
</html>
  1. Simpan file tersebut.

Anda telah menambahkan library web-vitals ke halaman web.

3 Mengukur Data Web Inti halaman web

Data Web Inti adalah ukuran pengalaman pengguna sebenarnya yang ditangkap melalui Chrome atau library web-vitals di browser Chromium. Saat merilis web-vitals ke tahap produksi, Anda akan melihat berbagai hasil berdasarkan kecepatan koneksi, daya perangkat, dan cara pengguna berinteraksi dengan situs Anda. Untuk mendemonstrasikan kemampuan library web-vitals, kita akan menyimulasikan pengalaman pengguna dengan koneksi yang lambat.

  1. Buka file yang tersimpan di browser web.
  2. Klik kanan halaman web.
  3. Klik Inspect untuk membuka Google Chrome Developer Tools.

1d60156133044215.png

  1. Klik tab Console > Console settings b5c716ebfacfd86.png.

a310e2b6e03891a1.png

  1. Pilih kotak centang Preserve log untuk membuat log tetap ada saat Anda memuat ulang halaman web.

cdfbcd3315aa45cd.png

  1. Klik tab Network > Online > Slow 3G untuk menyimulasikan koneksi jaringan lambat.

b1fab3d167d032f0.png

  1. Klik tab Console.
  2. Klik di mana saja pada halaman web guna memaksa metrik untuk Largest Contentful Paint (LCP) dan Penundaan Input Pertama (FID) agar mencetak.
  3. Klik Reload this page acaaa8c0fdd33b1.png guna memaksa metrik untuk Pergeseran Tata Letak Kumulatif (CLS) agar mencetak.

e18b530e48108a4.png

  1. Klik tab Network > Online > Fast 3G untuk menyimulasikan koneksi jaringan cepat.
  2. Klik tab Console.
  3. Klik di mana saja pada halaman web guna memaksa metrik untuk LCP dan FID agar mencetak lagi.

e5d5ca555ded9f7a.png

  1. Klik Reload this page acaaa8c0fdd33b1.png guna memaksa metrik untuk CLS agar mencetak lagi.

e8bde4594a01021b.png

Selesai. Anda telah mengukur Data Web Inti halaman web.

4. Menjelajahi data web-vitals secara lebih mendetail

Untuk setiap peristiwa Data Web Inti yang Anda ukur, tersedia sejumlah informasi dalam data yang ditampilkan yang dapat digunakan untuk men-debug bottleneck performa. Setiap peristiwa web-vitals berisi array entries dengan informasi tentang peristiwa yang berkontribusi pada nilai metrik saat ini.

entries CLS

Memperluas properti entries objek yang dicatat oleh getCLS() akan menampilkan daftar entri LayoutShift. Setiap LayoutShift berisi properti value yang mencerminkan skor pergeseran tata letak, dan array sources yang dapat kita gunakan untuk melihat elemen yang digeser.

355f0ff58e735079.png

Dalam contoh ini, akan terjadi dua pergeseran tata letak dan keduanya memindahkan elemen h1 di halaman. Properti currentRect memberi tahu kita letak elemen tersebut sekarang, dan elemen previousRect memberi tahu kita di mana posisi sebelumnya.

entries LCP

Memperluas properti entri objek yang dicatat ke dalam log oleh getLCP() akan menunjukkan elemen mana yang merupakan kandidat untuk Largest Contentful Paint (LCP) sebelum nilai akhir dilaporkan.

737ebf826005dbe7.png

Dalam contoh ini, array entries berisi daftar semua kandidat LCP dalam urutan kronologis. Dalam hal ini, elemen h1 dirender terlebih dahulu, baru kemudian elemen img. img adalah Largest Contentful Paint (LCP). Elemen LCP yang dilaporkan selalu menjadi item terakhir dalam array.

entries FID

Saat Anda memperluas properti entries objek yang dicatat oleh getFID(),, properti ini akan menampilkan array yang berisi entri PerformanceEventTiming untuk input pengguna pertama di halaman.

a63ef33575c3218d.png

Properti name memberi tahu Anda jenis input pengguna yang dapat memicu timer untuk ketersediaan thread utama. value yang dilaporkan oleh web-vitals adalah penundaan antara properti startTime dan processingStart entri PerformanceEventTiming yang dikonversi dari mikrodetik ke milidetik. Dalam hal ini, FID yang diukur adalah 2 milidetik.

5. Menyiapkan dan mengirim data web-vitals ke Google Analytics 4

Sebelum dapat mengirim data web-vitals ke Google Analytics 4, data tersebut perlu dikonversi ke format yang dapat diterima oleh GA4. Anda juga akan menambahkan beberapa fungsi berguna yang menampilkan informasi diagnostik yang penting.

Membuat pemilih untuk membantu mengidentifikasi node target entri

Pertama, tambahkan fungsi ke blok skrip yang menghasilkan representasi string dari node dan tempatnya di DOM, dalam format yang mirip dengan pemilih CSS. Output fungsi ini membantu mengidentifikasi elemen mana di halaman yang bertanggung jawab atas nilai CWV.

diagnostics.html

function getSelector(node, maxLen = 100) {
 let sel = '';
 try {
   while (node && node.nodeType !== 9) {
     const part = node.id ? '#' + node.id : node.nodeName.toLowerCase() + (
       (node.className && node.className.length) ?
       '.' + Array.from(node.classList.values()).join('.') : '');
     if (sel.length + part.length > maxLen - 1) return sel || part;
     sel = sel ? part + '>' + sel : part;
     if (node.id) break;
     node = node.parentNode;
   }
 } catch (err) {
   // Do nothing...
 }
 return sel;
}

Mengambil informasi LayoutShift

Mencatat setiap pergeseran tata letak yang terjadi kemungkinan akan menghasilkan jumlah data yang terlalu banyak. Fungsi di bawah hanya berfokus pada entri LayoutShift terbesar, dan LayoutShiftSource terbesar di dalamnya. Hal ini memungkinkan Anda memfokuskan pengoptimalan pada penyebab perubahan tata letak yang paling signifikan di situs. Saat Anda mengidentifikasi penyebab pergeseran tata letak dan menemukan cara untuk meminimalkannya, sumber pergeseran tata letak yang Anda lihat dalam laporan akan berubah sehingga pelanggar terburuk baru akan muncul.

diagnostics.html

function getLargestLayoutShiftEntry(entries) {
 return entries.reduce((a, b) => a && a.value > b.value ? a : b);
}

function getLargestLayoutShiftSource(sources) {
 return sources.reduce((a, b) => {
   return a.node && a.previousRect.width * a.previousRect.height >
       b.previousRect.width * b.previousRect.height ? a : b;
 });
}
  • getLargestLayoutShiftEntry() hanya menampilkan entri pergeseran tata letak terbesar selama siklus proses kunjungan halaman.
  • getLargestLayoutShiftSource() hanya menampilkan sumber pergeseran tata letak terbesar dalam entri tersebut.

Menentukan apakah FID terjadi sebelum atau setelah DOMContentLoaded

Peristiwa DOMContentLoaded terjadi setelah HTML halaman selesai dimuat dan diuraikan, yang mencakup menunggu pemuatan skrip sinkron, ditangguhkan, atau modul (termasuk semua modul yang diimpor secara statis). Fungsi ini menampilkan true jika input pengguna pertama terjadi sebelum DOMContentLoaded, atau false jika terjadi setelahnya.

diagnostics.html

function wasFIDBeforeDCL(fidEntry) {
 const navEntry = performance.getEntriesByType('navigation')[0];
 return navEntry && fidEntry.startTime < navEntry.domContentLoadedEventStart;
}

Mengidentifikasi elemen target FID

Sinyal debug lainnya yang mungkin penting adalah elemen yang diajak berinteraksi. Meskipun interaksi dengan elemen itu sendiri tidak berkontribusi pada FID (ingat, FID hanyalah bagian penundaan dari total latensi peristiwa), tetapi mengetahui elemen mana yang berinteraksi dengan pengguna Anda mungkin berguna untuk menentukan cara terbaik dalam mengoptimalkan FID.

Untuk mendapatkan elemen yang terkait dengan peristiwa input pertama, referensikan properti target entri first-input:

diagnostics.html

function getFIDDebugTarget(entries) {
  return entries[0].target;
}

Mengidentifikasi jenis peristiwa input FID

Tindakan ini juga penting untuk menangkap jenis peristiwa yang memicu pengukuran FID untuk mengidentifikasi cara pengguna berinteraksi dengan halaman Anda.

diagnostics.html

function getFIDEventType(entries) {
  return entries[0].name;
}

Menyusun informasi debug untuk setiap CWV

Langkah terakhir sebelum mengirim kode ini ke Google Analytics adalah menyusun informasi dari entri, termasuk informasi yang ditampilkan oleh fungsi di atas.

diagnostics.html

function getDebugInfo(name, entries = []) {
  // In some cases there won't be any entries (e.g. if CLS is 0,
  // or for LCP after a bfcache restore), so we have to check first.
  if (entries.length) {
    if (name === 'LCP') {
      const lastEntry = entries[entries.length - 1];
      return {
        debug_target: getSelector(lastEntry.element),
        event_time: lastEntry.startTime,
      };
    } else if (name === 'FID') {
      const firstEntry = entries[0];
      return {
        debug_target: getSelector(firstEntry.target),
        debug_event: firstEntry.name,
        debug_timing: wasFIDBeforeDCL(firstEntry) ? 'pre_dcl' : 'post_dcl',
        event_time: firstEntry.startTime,
      };
    } else if (name === 'CLS') {
      const largestEntry = getLargestLayoutShiftEntry(entries);
      if (largestEntry && largestEntry.sources && largestEntry.sources.length) {
        const largestSource = getLargestLayoutShiftSource(largestEntry.sources);
        if (largestSource) {
          return {
            debug_target: getSelector(largestSource.node),
            event_time: largestEntry.startTime,
          };
        }
      }
    }
  }
  // Return default/empty params in case there are no entries.
  return {
    debug_target: '(not set)',
  };
}

Mengirim data ke Google Analytics

Terakhir, buat fungsi yang menggunakan parameter dari peristiwa web-vitals dan meneruskannya ke Google Analytics.

diagnostics.html

function sendToGoogleAnalytics({ name, delta, value, id, entries }) {
  gtag('event', name, {
    // Built-in params:
    value: delta, // Use `delta` so the value can be summed.
    // Custom params:
    metric_id: id, // Needed to aggregate events.
    metric_value: value, // Value for querying in BQ
    metric_delta: delta, // Delta for querying in BQ
    // Send the returned values from getDebugInfo() as custom parameters
      ...getDebugInfo(name, entries)
  });
}

Daftarkan fungsi dengan setiap fungsi web-vitals, yang diaktifkan saat browser siap mengukur setiap peristiwa:

diagnostics.html

getLCP(sendToGoogleAnalytics);
getFID(sendToGoogleAnalytics);
getCLS(sendToGoogleAnalytics);

Bagus! Anda sekarang mengirim peristiwa web-vitals ke Google Analytics.

6. Memastikan data web-vitals terisi di Google Analytics

Untuk memastikan peristiwa Anda dicatat oleh properti Google Analytics 4:

  1. Buka properti Google Analytics 4 lalu buka Reports.

ab1bf51ba70f3609.png

  1. Pilih Realtime.

65a5b8087b09b2a.png

  1. Muat ulang halaman pengujian beberapa kali dan pastikan Anda mengklik halaman di antara pemuatan ulang tersebut untuk memicu peristiwa FID.
  2. Cari bagian Event count by Event name pada UI ringkasan Realtime. Anda akan melihat peristiwa LCP, FID, dan CLS.

f92b276df1c2f6ce.png

  1. Klik salah satu nama peristiwa untuk melihat parameter yang diteruskan dengan peristiwa tersebut.

8529bd743f121dd9.png

  1. Klik kunci parameter tersebut untuk melihat ringkasan nilai yang diterima Google Analytics.

f0cf6a3dd607d533.png

Anda mungkin ingin menambahkan data lain ke info debug, seperti nama template halaman atau peristiwa halaman lainnya yang relevan dengan FID yang telah dibahas sebelumnya di Codelab ini. Cukup ubah pernyataan return dalam fungsi getDebugInfo().

Setelah Anda puas dengan data yang berasal dari halaman pengujian, deploy kode GA baru ke tahap produksi di situs, lalu lanjutkan ke langkah berikutnya.

7. Membuat kueri data di BigQuery

Setelah kode Google Analytics aktif selama beberapa hari, Anda dapat mulai membuat kueri data di BigQuery. Pertama, periksa apakah data ditransfer ke BigQuery.

  1. Buka Google Cloud Console, lalu pilih project dari menu drop-down di bagian atas layar.
  2. Dari menu navigasi 3cbb0e5fcc230aef.png di kiri atas layar, klik BigQuery di bawah header Analytics.
  3. Di panel Explorer, luaskan project Anda untuk melihat set data Google Analytics. Nama set data adalah analytics_ diikuti dengan ID properti Google Analytics 4 Anda (misalnya, analytics_229787100).
  4. Luaskan set data dan Anda akan melihat tabel events_. Angka yang ada dalam tanda kurung adalah ketersediaan jumlah hari untuk kueri.

Subkueri untuk memilih peristiwa CWV saja

Untuk membuat kueri set data yang hanya mencakup peristiwa CWV, mulai dengan subkueri yang memilih 28 hari terakhir peristiwa LCP, CLS, dan FID. Proses ini secara khusus mencari nilai terakhir yang dilaporkan untuk setiap ID peristiwa web-vitals menggunakan kunci metric_id untuk memastikan peristiwa CWV yang sama tidak dihitung lebih dari sekali.

# Subquery all Web Vitals events from the last 28 days
WITH web_vitals_events AS (
 SELECT event_name as metric_name, * EXCEPT(event_name, is_last_received_value) FROM
 (
   SELECT *
   , IF (ROW_NUMBER() OVER (
     PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id')
     ORDER BY (SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = 'metric_value') DESC
   ) = 1, true, false) AS is_last_received_value
   # Make sure to update your project ID and GA4 property ID here!
   FROM `YOUR_PROJECT_ID.analytics_YOUR_GA_PROPERTY_ID.events_*`
   WHERE event_name in ('CLS', 'FID', 'LCP') AND
     _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 28 DAY)) AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY))
  )
  WHERE is_last_received_value
)

Ini akan menjadi dasar perbandingan dari semua kueri terhadap set data ini. Kueri utama akan dijalankan dengan membandingkannya ke tabel sementara web_vitals_events.

Cara peristiwa GA4 disusun

Setiap data peristiwa Google Analytics 4 disimpan dalam STRUCT kolom event_params. Setiap parameter peristiwa yang Anda teruskan ke GA4 di situs akan diwakili oleh kuncinya, dan nilainya adalah STRUCT dengan kunci untuk setiap jenis data yang mungkin. Pada contoh di atas, kunci metric_value dapat memiliki int_value atau double_value, sehingga fungsi COALESCE() digunakan. Untuk mendapatkan debug_target yang Anda teruskan sebelumnya, pilih kunci string_value di debug_target.

...
(SELECT value.string_value FROM UNNEST(event_params) WHERE key = "debug_target") as debug_target
...

Menemukan halaman dan elemen dengan performa terburuk

debug_target adalah string pemilih CSS yang sesuai dengan elemen di halaman yang paling relevan dengan nilai metrik.

Dengan CLS, debug_target akan merepresentasikan elemen terbesar dari pergeseran tata letak terbesar yang berkontribusi pada nilai CLS. Jika tidak ada elemen yang digeser, nilai debug_target adalah null.

Kueri berikut mencantumkan halaman dari yang terburuk hingga terbaik berdasarkan CLS-nya di persentil ke-75 yang dikelompokkan berdasarkan debug_target:

# Main query logic
SELECT
  page_path,
  debug_target,
  APPROX_QUANTILES(metric_value, 100)[OFFSET(75)] AS metric_p75,
  COUNT(1) as page_views
FROM (
  SELECT
    REGEXP_SUBSTR((SELECT value.string_value FROM UNNEST(event_params) WHERE key = "page_location"), r'\.com(\/[^?]*)') AS page_path,
    (SELECT value.string_value FROM UNNEST(event_params) WHERE key = "debug_target") as debug_target,
    ROUND((SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = "metric_value"), 3) AS metric_value,
    *
  FROM web_vitals_events
  WHERE metric_name = 'CLS'
)
GROUP BY 1, 2
# OPTIONAL: You may want to limit your calculations to pages with a
# minimum number of pageviews to reduce noise in your reports.
# HAVING page_views > 50
ORDER BY metric_p75 DESC

1bbbd957b4292ced.png

Identifikasi dan perbaikan akar penyebab masalah akan lebih mudah jika Anda dapat mengetahui elemen yang mengalami perubahan di halaman.

Perlu diingat bahwa elemen yang dilaporkan di sini mungkin bukan elemen yang mengalami perubahan ketika Anda men-debug halaman secara lokal. Itulah sebabnya penting untuk mengumpulkan data ini dari awal. Memperbaiki masalah yang tidak Anda sadari sangat sulit.

Men-debug metrik lainnya

Kueri di atas menunjukkan hasil untuk metrik CLS, tetapi teknik yang sama persis dapat digunakan untuk melaporkan target debug untuk LCP dan FID. Cukup ganti klausul WHERE dengan metrik yang relevan untuk melakukan debug:

# Replace:
# WHERE metric_name = 'CLS'
# With:
WHERE metric_name = 'LCP'

8. Memvisualisasikan hasil kueri di Data Studio

BigQuery menyediakan cara cepat untuk memvisualisasikan hasil kueri melalui Data Studio. Data Studio adalah alat dasbor dan visualisasi data yang dapat digunakan secara gratis. Untuk memvisualisasikan hasil kueri setelah menjalankan kueri di UI BigQuery, klik Explore data lalu pilih Explore with Data Studio.

Opsi Explore with Data Studio di BigQuery

Opsi ini akan membuat link langsung dari BigQuery ke Data Studio dalam tampilan eksplorasi. Dalam tampilan ini, Anda dapat memilih kolom yang ingin divisualisasikan, memilih jenis diagram, menyiapkan filter, dan membuat diagram ad hoc untuk analisis visual yang cepat. Dari hasil kueri di atas, Anda dapat membuat diagram garis ini untuk melihat tren nilai LCP secara bertahap:

Diagram garis nilai LCP harian di Data Studio

Dengan link langsung antara BigQuery dan Data Studio ini, Anda dapat membuat diagram cepat dari kueri mana pun dan melakukan analisis visual. Namun, jika Anda ingin melakukan analisis tambahan, sebaiknya lihat beberapa diagram di dasbor interaktif untuk mendapatkan gambaran yang lebih menyeluruh atau untuk melihat perincian data. Dengan adanya dasbor yang praktis ini, Anda tidak perlu menulis kueri dan membuat diagram secara manual setiap kali ingin menganalisis metrik.

Anda dapat membuat dasbor di Data Studio menggunakan konektor BigQuery native. Untuk melakukannya, buka datastudio.google.com, buat sumber data baru, pilih konektor BigQuery, lalu pilih set data yang ingin Anda gunakan:

Menggunakan konektor native BigQuery di Data Studio

9. Mewujudkan data Data Web

Saat membuat dasbor data peristiwa Data Web seperti yang dijelaskan di atas, menggunakan set data ekspor Google Analytics 4 secara langsung bukanlah cara yang efisien. Sebagian kueri Anda akhirnya berjalan beberapa kali karena struktur data GA4 dan pra-pemrosesan yang diperlukan untuk metrik Data Web. Hal ini menimbulkan dua masalah: performa dasbor dan biaya BigQuery.

Anda dapat menggunakan mode sandbox BigQuery secara gratis. Dengan paket penggunaan gratis BigQuery, 1 TB data kueri pertama yang diproses per bulan tidak akan dipungut biaya. Untuk metode analisis yang dibahas dalam postingan ini, Anda dapat tetap berada dalam batas gratis ini setiap bulan kecuali Anda menggunakan set data yang sangat besar atau sering membuat kueri set data secara rutin. Namun, jika Anda memiliki sebuah situs dengan traffic tinggi dan ingin memantau metrik yang berbeda secara rutin menggunakan dasbor interaktif yang cepat, sebaiknya lakukan pra-pemrosesan dan mewujudkan data web Anda sambil memanfaatkan fitur efisiensi BigQuery seperti pembuatan partisi, pengelompokan, dan caching.

Skrip berikut memproses data BigQuery (tabel sumber) terlebih dahulu dan membuat tabel yang diwujudkan (tabel target).

# Materialize Web Vitals metrics from GA4 event export data

# Replace target table name
CREATE OR REPLACE TABLE YOUR_PROJECT_ID.analytics_YOUR_GA_PROPERTY_ID.web_vitals_summary
  PARTITION BY DATE(event_timestamp)
AS
SELECT
  ga_session_id,
  IF(
    EXISTS(SELECT 1 FROM UNNEST(events) AS e WHERE e.event_name = 'first_visit'),
    'New user',
    'Returning user') AS user_type,
  IF(
    (SELECT MAX(session_engaged) FROM UNNEST(events)) > 0, 'Engaged', 'Not engaged')
    AS session_engagement,
  evt.* EXCEPT (session_engaged, event_name),
  event_name AS metric_name,
  FORMAT_TIMESTAMP('%Y%m%d', event_timestamp) AS event_date
FROM
  (
    SELECT
      ga_session_id,
      ARRAY_AGG(custom_event) AS events
    FROM
      (
        SELECT
          ga_session_id,
          STRUCT(
            country,
            device_category,
            device_os,
            traffic_medium,
            traffic_name,
            traffic_source,
            page_path,
            debug_target,
            event_timestamp,
            event_name,
            metric_id,
            IF(event_name = 'LCP', metric_value / 1000, metric_value) AS metric_value,
            user_pseudo_id,
            session_engaged,
            session_revenue) AS custom_event
        FROM
          (
            SELECT
              (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id')
                AS ga_session_id,
              (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id')
                AS metric_id,
              ANY_VALUE(device.category) AS device_category,
              ANY_VALUE(device.operating_system) AS device_os,
              ANY_VALUE(traffic_source.medium) AS traffic_medium,
              ANY_VALUE(traffic_source.name) AS traffic_name,
              ANY_VALUE(traffic_source.source) AS traffic_source,
              ANY_VALUE(
                REGEXP_SUBSTR(
                  (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'page_location'),
                  r'^[^?]+')) AS page_path,
              ANY_VALUE(
                (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'debug_target'))
                AS debug_target,
              ANY_VALUE(user_pseudo_id) AS user_pseudo_id,
              ANY_VALUE(geo.country) AS country,
              ANY_VALUE(event_name) AS event_name,
              SUM(ecommerce.purchase_revenue) AS session_revenue,
              MAX(
                (
                  SELECT
                    COALESCE(
                      value.double_value, value.int_value, CAST(value.string_value AS NUMERIC))
                  FROM UNNEST(event_params)
                  WHERE key = 'session_engaged'
                )) AS session_engaged,
              TIMESTAMP_MICROS(MAX(event_timestamp)) AS event_timestamp,
              MAX(
                (
                  SELECT COALESCE(value.double_value, value.int_value)
                  FROM UNNEST(event_params)
                  WHERE key = 'metric_value'
                )) AS metric_value,
            FROM
              # Replace source table name
              `YOUR_PROJECT_ID.analytics_YOUR_GA_PROPERTY_ID.events_*`
            WHERE
              event_name IN ('LCP', 'FID', 'CLS', 'first_visit', 'purchase')
            GROUP BY
              1, 2
          )
      )
    WHERE
      ga_session_id IS NOT NULL
    GROUP BY ga_session_id
  )
CROSS JOIN UNNEST(events) AS evt
WHERE evt.event_name NOT IN ('first_visit', 'purchase');

Set data terwujud ini memiliki beberapa keuntungan:

  • Struktur data diratakan dan lebih mudah untuk dikueri.
  • Data ini hanya mempertahankan peristiwa Data Web dari set data GA4 asli.
  • ID sesi, jenis pengguna (baru vs. yang kembali), dan informasi interaksi sesi tersedia langsung di kolom.
  • Tabel dipartisi berdasarkan tanggal dan dikelompokkan menurut nama metrik. Tindakan ini biasanya mengurangi jumlah data yang diproses untuk setiap kueri.
  • Anda tidak perlu menggunakan karakter pengganti untuk membuat kueri pada tabel ini sehingga hasil kueri dapat di-cache hingga 24 jam. Cara ini dapat mengurangi biaya dari pengulangan kueri yang sama.
  • Jika menggunakan BigQuery BI Engine, Anda dapat menjalankan fungsi dan operator SQL yang dioptimalkan pada tabel ini.

Anda dapat langsung membuat kueri tabel yang diwujudkan dari UI BigQuery, atau menggunakannya di Data Studio menggunakan konektor BigQuery.

Menjalankan tugas yang diwujudkan secara teratur

Jika Anda menjalankan kueri di atas tanpa rentang tanggal, kueri akan berjalan di seluruh set data Google Analytics. Sebaiknya jangan lakukan hal ini setiap hari, karena Anda akan memproses ulang sejumlah besar data historis. Anda dapat memperbarui kueri agar hanya bisa menambahkan data hari terakhir dengan menghapus pernyataan CREATE or REPLACE TABLE di awal kueri, dan menambahkan kriteria tambahan ke klausul WHERE di subkueri terhadap tabel events_intraday_:

FROM
  # Replace source table name
  `YOUR_PROJECT_ID.analytics_YOUR_GA_PROPERTY_ID.events_intraday_*`
WHERE
  event_name IN ('LCP', 'FID', 'CLS', 'first_visit', 'purchase')
  # The _TABLE_SUFFIX replaces the asterisk (*) in the table name
  #
  AND _TABLE_SUFFIX = FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY)

Kueri ini hanya menampilkan data kemarin. Anda kemudian dapat menggunakan Konsol BigQuery untuk menjadwalkan kueri untuk dijalankan setiap hari.

10. Memvisualisasikan data di Google Data Studio

Google Data Studio secara native mendukung pembacaan data dari Google BigQuery. Setelah memiliki data web-vitals dari Google Analytics 4 yang terisi di BigQuery, Anda dapat menggunakan konektor BigQuery Data Studio untuk langsung membaca tabel yang diwujudkan.

Menggunakan Konektor Data Web

Karena membuat dasbor dari awal memakan banyak waktu, kami mengembangkan solusi terpaket yang membuat dasbor template untuk Anda. Pertama, pastikan Anda telah mewujudkan tabel Data Web menggunakan kueri di atas. Kemudian, akses konektor Data Web untuk Data Studio menggunakan link ini: goo.gle/web-vitals-connector

Setelah memberikan otorisasi satu kali, Anda akan melihat layar konfigurasi berikut:

Layar otorisasi Web Vitals Connector

Berikan ID tabel BigQuery yang terwujud (yaitu tabel target) dan project ID penagihan BigQuery Anda. Setelah mengklik CONNECT, Data Studio akan membuat dasbor template baru dan mengaitkan data Anda dengan dasbor tersebut. Anda dapat mengedit, mengubah, dan membagikan dasbor sesuai keinginan. Jika membuat dasbor satu kali, Anda tidak perlu mengunjungi link konektor lagi, kecuali jika ingin membuat beberapa dasbor dari berbagai set data.

Saat membuka dasbor, Anda dapat melihat tren harian metrik Data Web dan beberapa informasi penggunaan untuk situs Anda seperti pengguna dan sesi, di tab Ringkasan.

Di tab Analisis Pengguna, Anda dapat memilih metrik dan mendapatkan perincian persentil metrik, serta jumlah pengguna, berdasarkan berbagai metrik penggunaan dan bisnis.

Tab Analisis Jalur Halaman membantu Anda mengidentifikasi area masalah di situs Anda. Di sini, Anda tidak hanya dapat memilih metrik untuk melihat ringkasan, tetapi juga melihat peta sebar semua jalur halaman dengan nilai persentil di sumbu y dan mencatat jumlah pada sumbu x. Peta sebar dapat membantu mengidentifikasi halaman yang memiliki nilai metrik di bawah perkiraan. Setelah memilih halaman, Anda dapat melihat perincian lebih lanjut pada area masalah dengan diagram sebar pada tabel Jalur halaman, atau dengan melihat tabel Target Debug.

Tab Analisis Pendapatan adalah contoh cara memantau metrik bisnis dan performa di tempat yang sama. Bagian ini merencanakan semua sesi saat pengguna melakukan pembelian. Anda dapat membandingkan pendapatan yang diperoleh dengan pengalaman pengguna selama sesi tertentu.

11. Referensi lainnya

Selamat, Anda telah menyelesaikan Codelab ini. Sekarang Anda seharusnya dapat melacak performa Data Web Inti di seluruh situs dengan tingkat perincian yang tinggi. Anda juga seharusnya dapat mengidentifikasi elemen dan jenis halaman tertentu di situs Anda yang menyebabkan CWV tinggi, sehingga Anda dapat memfokuskan pengoptimalan.

Bacaan lebih lanjut

web.dev memiliki banyak artikel dan studi kasus dengan strategi untuk meningkatkan Data Web Inti. Mulailah dengan artikel pengoptimalan untuk setiap metrik:

Dokumen referensi