Pelajari cara mengatribusikan data performa dengan informasi debug untuk membantu mengidentifikasi dan memperbaiki masalah pengguna nyata dengan analisis
Google menyediakan dua kategori alat untuk mengukur dan melakukan debug performa:
- Alat Lab: Alat seperti Lighthouse, tempat halaman Anda dimuat di lingkungan simulasi yang dapat meniru berbagai kondisi (misalnya, jaringan lambat dan perangkat seluler kelas bawah).
- Alat kolom: Alat seperti Laporan Pengalaman Pengguna Chrome (CrUX), yang didasarkan pada data gabungan pengguna nyata dari Chrome. (Perhatikan bahwa data kolom yang dilaporkan oleh alat seperti PageSpeed Insights dan Search Console berasal dari data CrUX.)
Meskipun alat lapangan menawarkan data yang lebih akurat—data yang benar-benar mewakili pengalaman pengguna yang nyata—alat lab sering kali lebih baik dalam membantu Anda mengidentifikasi dan memperbaiki masalah.
Data CrUX lebih merepresentasikan performa halaman Anda yang sebenarnya, tetapi mengetahui skor CrUX kemungkinan tidak akan membantu Anda mengetahui cara meningkatkan performa.
Di sisi lain, Lighthouse akan mengidentifikasi masalah dan membuat saran khusus tentang cara meningkatkan kualitasnya. Namun, Lighthouse hanya akan memberikan saran untuk masalah performa yang ditemukannya pada waktu pemuatan halaman. Fitur ini tidak mendeteksi masalah yang hanya muncul sebagai hasil dari interaksi pengguna seperti men-scroll atau mengklik tombol di halaman.
Hal ini menimbulkan pertanyaan penting: bagaimana cara mengambil informasi debug untuk Data Web Inti atau metrik performa lainnya dari pengguna sungguhan di lapangan?
Postingan ini akan menjelaskan secara mendetail API yang dapat Anda gunakan untuk mengumpulkan informasi proses debug tambahan untuk setiap metrik Data Web Inti saat ini dan memberikan ide tentang cara mengambil data ini di alat analisis yang sudah ada.
API untuk atribusi dan proses debug
CLS
Dari semua metrik Data Web Inti, CLS mungkin adalah salah satu yang paling penting untuk mengumpulkan informasi debug di kolom. CLS diukur sepanjang masa aktif halaman, sehingga cara pengguna berinteraksi dengan halaman—seberapa jauh mereka men-scroll, apa yang mereka klik, dan sebagainya—dapat berdampak signifikan pada apakah ada pergeseran tata letak dan elemen mana yang bergeser.
Pertimbangkan laporan berikut dari PageSpeed Insights:
Nilai yang dilaporkan untuk CLS dari lab (Lighthouse) dibandingkan dengan CLS dari kolom (data CrUX) sangat berbeda, dan ini masuk akal jika Anda mempertimbangkan bahwa halaman tersebut mungkin memiliki banyak konten interaktif yang tidak digunakan saat diuji di Lighthouse.
Namun, meskipun Anda memahami bahwa interaksi pengguna memengaruhi data lapangan, Anda tetap perlu mengetahui elemen apa saja pada halaman tersebut yang mengalami pergeseran untuk menghasilkan skor 0,3 pada persentil ke-75.
Antarmuka LayoutShiftAttribution memungkinkan hal itu.
Mendapatkan atribusi pergeseran tata letak
Antarmuka LayoutShiftAttribution
ditampilkan pada setiap entri layout-shift
yang dihasilkan Layout Instability
API.
Untuk penjelasan mendetail tentang kedua antarmuka ini, lihat Men-debug pergeseran tata letak. Untuk tujuan postingan ini, hal utama yang perlu Anda ketahui adalah, sebagai developer, Anda dapat mengamati setiap pergeseran tata letak yang terjadi di halaman serta elemen apa saja yang bergeser.
Berikut adalah beberapa kode contoh yang mencatat setiap pergeseran tata letak serta elemen yang bergeser ke dalam log:
new PerformanceObserver((list) => {
for (const {value, startTime, sources} of list.getEntries()) {
// Log the shift amount and other entry info.
console.log('Layout shift:', {value, startTime});
if (sources) {
for (const {node, curRect, prevRect} of sources) {
// Log the elements that shifted.
console.log(' Shift source:', node, {curRect, prevRect});
}
}
}
}).observe({type: 'layout-shift', buffered: true});
Mungkin tidak praktis untuk mengukur dan mengirim data ke alat analisis untuk setiap pergeseran tata letak yang terjadi. Namun, dengan memantau semua shift, Anda dapat melacak perubahan terburuk dan hanya melaporkan informasinya.
Sasarannya bukan untuk mengidentifikasi dan memperbaiki setiap pergeseran tata letak yang terjadi untuk setiap pengguna; tujuannya adalah mengidentifikasi perubahan yang memengaruhi jumlah pengguna terbanyak sehingga memberikan kontribusi terbesar untuk CLS halaman Anda pada persentil ke-75.
Selain itu, Anda tidak perlu menghitung elemen sumber terbesar setiap kali ada perubahan. Anda hanya perlu melakukannya saat sudah siap mengirimkan nilai CLS ke alat analisis.
Kode berikut mengambil daftar entri layout-shift
yang telah berkontribusi
pada CLS dan menampilkan elemen sumber terbesar dari pergeseran terbesar:
function getCLSDebugTarget(entries) {
const largestEntry = entries.reduce((a, b) => {
return a && a.value > b.value ? a : b;
});
if (largestEntry && largestEntry.sources && largestEntry.sources.length) {
const largestSource = largestEntry.sources.reduce((a, b) => {
return a.node && a.previousRect.width * a.previousRect.height >
b.previousRect.width * b.previousRect.height ? a : b;
});
if (largestSource) {
return largestSource.node;
}
}
}
Setelah mengidentifikasi elemen terbesar yang berkontribusi pada perubahan terbesar, Anda dapat melaporkannya ke alat analisis.
Elemen yang paling banyak berkontribusi pada CLS untuk halaman tertentu mungkin akan bervariasi dari satu pengguna ke pengguna lainnya, tetapi jika Anda menggabungkan elemen tersebut dari semua pengguna, Anda akan dapat membuat daftar elemen yang bergeser yang memengaruhi sebagian besar pengguna.
Setelah Anda mengidentifikasi dan memperbaiki penyebab utama pergeseran untuk elemen tersebut, kode analisis Anda akan mulai melaporkan pergeseran yang lebih kecil sebagai pergeseran "terburuk" untuk halaman Anda. Pada akhirnya, semua perubahan yang dilaporkan akan cukup kecil sehingga halaman Anda berada dalam batas "baik" yaitu 0,1.
Beberapa metadata lain yang mungkin berguna untuk diambil bersama dengan elemen sumber shift terbesar adalah:
- Waktu pergantian karyawan terbesar
- Jalur URL pada saat perubahan terbesar (untuk situs yang memperbarui URL secara dinamis, seperti Aplikasi Web Satu Halaman).
LCP
Untuk men-debug LCP di kolom, informasi utama yang Anda perlukan adalah elemen tertentu yang merupakan elemen terbesar (elemen kandidat LCP) untuk pemuatan halaman tertentu.
Perhatikan bahwa sangat mungkin—bahkan sangat umum—bahwa elemen kandidat LCP akan berbeda dari satu pengguna ke pengguna lainnya, bahkan untuk halaman yang sama persis.
Hal ini dapat terjadi karena beberapa alasan:
- Perangkat pengguna memiliki resolusi layar yang berbeda, sehingga menyebabkan tata letak halaman yang berbeda sehingga elemen yang berbeda terlihat dalam area pandang.
- Pengguna tidak selalu memuat halaman yang di-scroll ke bagian paling atas. Sering kali, link akan berisi ID fragmen atau bahkan fragmen teks, yang berarti halaman Anda dapat dimuat dan ditampilkan pada posisi scroll mana pun di halaman.
- Konten dapat dipersonalisasi untuk pengguna saat ini, sehingga elemen kandidat LCP dapat sangat bervariasi dari satu pengguna ke pengguna lainnya.
Artinya, Anda tidak dapat membuat asumsi tentang elemen atau kumpulan elemen mana yang akan menjadi elemen kandidat LCP yang paling umum untuk halaman tertentu. Anda harus mengukurnya berdasarkan perilaku pengguna yang sebenarnya.
Mengidentifikasi elemen kandidat LCP
Untuk menentukan elemen kandidat LCP di JavaScript, Anda dapat menggunakan Largest Contentful Paint API, API yang sama yang Anda gunakan untuk menentukan nilai waktu LCP.
Saat mengamati entri largest-contentful-paint
, Anda dapat menentukan
elemen kandidat LCP saat ini dengan melihat properti element
entri terakhir:
new PerformanceObserver((list) => {
const entries = list.getEntries();
const lastEntry = entries[entries.length - 1];
console.log('LCP element:', lastEntry.element);
}).observe({type: 'largest-contentful-paint', buffered: true});
Setelah mengetahui elemen kandidat LCP, Anda dapat mengirimkannya ke alat analisis beserta nilai metriknya. Seperti halnya CLS, hal ini akan membantu Anda mengidentifikasi elemen yang paling penting untuk dioptimalkan terlebih dahulu.
Selain elemen kandidat LCP, sebaiknya ukur waktu sub-bagian LCP, yang dapat berguna dalam menentukan langkah pengoptimalan tertentu yang relevan untuk situs Anda.
FID
Untuk men-debug FID di kolom ini, perlu diingat bahwa FID hanya mengukur bagian penundaan dari keseluruhan latensi peristiwa input pertama. Artinya, hal yang berinteraksi dengan pengguna tidak sepenting hal lain yang terjadi di thread utama pada saat mereka berinteraksi.
Misalnya, banyak aplikasi JavaScript yang mendukung rendering sisi server (SSR) akan mengirim HTML statis yang dapat dirender ke layar sebelum interaktif dengan input pengguna—yaitu, sebelum JavaScript yang diperlukan untuk membuat konten interaktif selesai dimuat.
Untuk jenis aplikasi ini, sangat penting untuk mengetahui apakah input pertama terjadi sebelum atau setelah hidrasi. Jika ternyata banyak orang mencoba berinteraksi dengan halaman sebelum hidrasi selesai, pertimbangkan untuk merender halaman Anda dalam status nonaktif atau pemuatan, bukan dalam status yang terlihat interaktif.
Jika framework aplikasi mengekspos stempel waktu hidrasi, Anda dapat
membandingkannya dengan stempel waktu entri first-input
untuk menentukan apakah
input pertama terjadi sebelum atau setelah hidrasi. Jika framework Anda tidak
mengekspos stempel waktu tersebut, atau tidak menggunakan hidrasi sama sekali, sinyal lain yang berguna
mungkin berupa input yang terjadi sebelum atau setelah JavaScript selesai dimuat.
Peristiwa DOMContentLoaded
diaktifkan setelah HTML halaman dimuat dan diuraikan sepenuhnya, termasuk menunggu skrip sinkron, ditangguhkan, atau modul (termasuk semua modul yang diimpor secara statis) untuk dimuat. Jadi Anda dapat menggunakan waktu dari
peristiwa itu dan membandingkannya dengan saat FID terjadi.
Kode berikut mengamati entri dan log first-input
terlepas dari apakah input pertama terjadi sebelum akhir peristiwa DOMContentLoaded
atau tidak:
new PerformanceObserver((list) => {
const fidEntry = list.getEntries()[0];
const navEntry = performance.getEntriesByType('navigation')[0];
const wasFIDBeforeDCL =
fidEntry.startTime < navEntry.domContentLoadedEventStart;
console.log('FID occurred before DOMContentLoaded:', wasFIDBeforeDCL);
}).observe({type: 'first-input', buffered: true});
Mengidentifikasi elemen target dan jenis peristiwa FID
Sinyal debug tambahan yang berpotensi berguna adalah elemen yang berinteraksi
serta jenis interaksinya (seperti mousedown
, keydown
,
pointerdown
). Meskipun interaksi dengan elemen itu sendiri tidak
berkontribusi pada FID (ingat, FID hanyalah bagian penundaan dari total latensi
peristiwa), mengetahui elemen mana yang berinteraksi dengan pengguna mungkin akan berguna
dalam menentukan cara terbaik untuk meningkatkan FID.
Misalnya, jika sebagian besar interaksi pertama pengguna Anda dilakukan dengan elemen tertentu, pertimbangkan untuk menyisipkan kode JavaScript yang diperlukan untuk elemen tersebut di HTML, dan menjalankan pemuatan lambat sisanya.
Untuk mendapatkan jenis interaksi dan elemen yang terkait dengan peristiwa input pertama, Anda dapat mereferensikan properti target
dan name
entri first-input
:
new PerformanceObserver((list) => {
const fidEntry = list.getEntries()[0];
console.log('FID target element:', fidEntry.target);
console.log('FID interaction type:', fidEntry.name);
}).observe({type: 'first-input', buffered: true});
INP
INP sangat mirip dengan FID karena bit informasi yang paling berguna untuk diambil di lapangan adalah:
- Elemen apa yang berinteraksi
- Alasan jenis interaksi
- Kapan interaksi itu terjadi
Seperti FID, penyebab utama lambatnya interaksi adalah thread utama yang diblokir, yang dapat terjadi ketika JavaScript sedang dimuat. Mengetahui apakah sebagian besar interaksi lambat terjadi selama pemuatan halaman akan membantu dalam menentukan tindakan yang harus dilakukan untuk memperbaiki masalah.
Tidak seperti FID, metrik INP mempertimbangkan latensi penuh dari interaksi—termasuk waktu yang diperlukan untuk menjalankan pemroses peristiwa yang terdaftar serta waktu yang diperlukan untuk menggambar frame berikutnya setelah semua pemroses peristiwa berjalan. Artinya, untuk INP, akan lebih bermanfaat untuk mengetahui elemen target mana yang cenderung menghasilkan interaksi yang lambat, dan jenis interaksi apa itu.
Karena INP dan FID didasarkan pada Event Timing API, cara Anda menentukan
informasi ini di JavaScript sangat mirip dengan contoh sebelumnya. Kode
berikut mencatat elemen dan waktu target (relatif terhadap DOMContentLoaded
)
entri INP ke dalam log.
function logINPDebugInfo(inpEntry) {
console.log('INP target element:', inpEntry.target);
console.log('INP interaction type:', inpEntry.name);
const navEntry = performance.getEntriesByType('navigation')[0];
const wasINPBeforeDCL =
inpEntry.startTime < navEntry.domContentLoadedEventStart;
console.log('INP occurred before DCL:', wasINPBeforeDCL);
}
Perhatikan bahwa kode ini tidak menunjukkan cara menentukan entri event
mana yang merupakan entri
INP, karena logika tersebut lebih terlibat. Namun, bagian berikut menjelaskan
cara mendapatkan informasi ini menggunakan
library JavaScript web-vitals.
Penggunaan dengan library JavaScript web-vitals
Bagian di atas menawarkan beberapa saran umum dan contoh kode untuk mengambil info debug yang akan disertakan dalam data yang Anda kirim ke alat analisis.
Sejak versi 3, library JavaScript web-vitals menyertakan build atribusi yang menampilkan semua informasi ini, dan juga beberapa sinyal tambahan.
Contoh kode berikut menunjukkan cara menetapkan parameter peristiwa tambahan (atau dimensi kustom) yang berisi string debug yang berguna untuk membantu mengidentifikasi penyebab utama masalah performa.
import {onCLS, onFID, onINP, onLCP} from 'web-vitals/attribution';
function sendToGoogleAnalytics({name, value, id, attribution}) {
const eventParams = {
metric_value: value,
metric_id: id,
}
switch (name) {
case 'CLS':
eventParams.debug_target = attribution.largestShiftTarget;
break;
case 'LCP':
eventParams.debug_target = attribution.element;
break;
case 'FID':
case 'INP':
eventParams.debug_target = attribution.eventTarget;
break;
}
// Assumes the global `gtag()` function exists, see:
// https://developers.google.com/analytics/devguides/collection/ga4
gtag('event', name, eventParams);
}
onCLS(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
onFID(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);
Kode ini khusus untuk Google Analytics, tetapi ide umumnya juga harus diterjemahkan ke alat analisis lainnya.
Kode ini juga hanya menunjukkan cara melaporkan satu sinyal debug, tetapi mungkin
berguna jika Anda dapat mengumpulkan dan melaporkan beberapa sinyal yang berbeda per
metrik. Misalnya, untuk men-debug INP, Anda mungkin ingin mengumpulkan jenis
interaksi, waktu, dan juga elemen tempat interaksi terjadi. Build atribusi
web-vitals
mengekspos semua informasi ini, seperti yang ditunjukkan pada contoh
berikut:
import {onCLS, onFID, onINP, onLCP} from 'web-vitals/attribution';
function sendToGoogleAnalytics({name, value, id, attribution}) {
const eventParams = {
metric_value: value,
metric_id: id,
}
switch (name) {
case 'INP':
eventParams.debug_target = attribution.eventTarget;
eventParams.debug_type = attribution.eventType;
eventParams.debug_time = attribution.eventTime;
eventParams.debug_load_state = attribution.loadState;
break;
// Additional metric logic...
}
// Assumes the global `gtag()` function exists, see:
// https://developers.google.com/analytics/devguides/collection/ga4
gtag('event', name, eventParams);
}
onCLS(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
onFID(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);
Lihat dokumentasi atribusi web-vitals untuk mengetahui daftar lengkap sinyal debug yang diekspos.
Melaporkan dan memvisualisasikan data
Setelah Anda mulai mengumpulkan informasi debug beserta nilai metrik, langkah berikutnya adalah menggabungkan data dari semua pengguna untuk mulai mencari pola dan tren.
Seperti yang disebutkan di atas, Anda tidak perlu mengatasi setiap masalah yang dihadapi pengguna. Anda ingin mengatasi—terutama di awal—masalah yang memengaruhi jumlah pengguna terbesar, yang juga harus berupa masalah yang memiliki dampak negatif terbesar pada skor Data Web Inti Anda.
Untuk GA4, lihat artikel khusus tentang cara membuat kueri dan memvisualisasikan data menggunakan BigQuery.
Ringkasan
Semoga postingan ini dapat membantu menjelaskan cara spesifik untuk menggunakan
API performa yang ada dan library web-vitals
untuk mendapatkan informasi debug
guna membantu mendiagnosis performa berdasarkan kunjungan pengguna yang sebenarnya di lapangan. Meskipun panduan ini berfokus pada Data Web Inti, konsepnya juga berlaku untuk proses debug
metrik performa yang dapat diukur di JavaScript.
Jika Anda baru mulai mengukur performa, dan sudah menjadi pengguna Google Analytics, alat Laporan Data Web mungkin bisa menjadi pilihan yang bagus untuk memulai, karena alat ini sudah mendukung pelaporan informasi debug untuk metrik Vitals Web Inti.
Jika Anda adalah vendor analisis dan ingin meningkatkan kualitas produk serta memberikan lebih banyak informasi proses debug kepada pengguna, pertimbangkan beberapa teknik yang dijelaskan di sini, tetapi jangan membatasi diri pada hanya ide yang ditampilkan di sini. Postingan ini secara umum dimaksudkan agar berlaku untuk semua alat analisis; namun, setiap alat analisis kemungkinan dapat (dan seharusnya) dapat (dan seharusnya) mengambil dan melaporkan lebih banyak lagi informasi debug.
Terakhir, jika Anda merasa ada kekurangan kemampuan untuk men-debug metrik ini karena kehilangan fitur atau informasi dalam API itu sendiri, kirimkan masukan Anda ke web-vitals-feedback@googlegroups.com.