Secara historis, developer web mengalami kesulitan untuk mengukur seberapa cepat konten utama halaman web dimuat dan terlihat oleh pengguna. Metrik lama seperti load atau DOMContentLoaded tidak berfungsi dengan baik karena tidak selalu sesuai dengan yang dilihat pengguna di layar mereka. Selain itu, metrik performa baru yang berfokus pada pengguna seperti First Contentful Paint (FCP) hanya menangkap awal pengalaman pemuatan. Jika halaman menampilkan layar pembuka atau menampilkan indikator pemuatan, momen ini tidak terlalu relevan bagi pengguna.
Sebelumnya, kami telah merekomendasikan metrik performa seperti First Meaningful Paint (FMP) dan Speed Index (SI) (keduanya tersedia di Lighthouse) untuk membantu menangkap lebih banyak pengalaman pemuatan setelah proses rendering awal, tetapi metrik ini kompleks, sulit dijelaskan, dan sering kali salah—artinya metrik ini masih belum mengidentifikasi kapan konten utama halaman dimuat.
Berdasarkan diskusi di W3C Web Performance Working Group dan riset yang dilakukan di Google, kami mendapati bahwa cara yang lebih akurat untuk mengukur kapan konten utama halaman dimuat adalah dengan melihat kapan elemen terbesar dirender.
Apa itu LCP?
LCP melaporkan waktu render gambar, blok teks, atau video terbesar yang terlihat di area pandang, dibandingkan saat pengguna pertama kali membuka halaman.
Seperti apa skor LCP yang baik?
Untuk memberikan pengalaman pengguna yang baik, situs harus berusaha memiliki Largest Contentful Paint selama 2,5 detik atau kurang. Untuk memastikan Anda mencapai target ini bagi sebagian besar pengguna, nilai minimum yang baik untuk diukur adalah persentil ke-75 pemuatan halaman, yang disegmentasikan di seluruh perangkat seluler dan desktop.
Elemen apa saja yang dipertimbangkan?
Seperti yang saat ini ditentukan dalam Largest Contentful Paint API, jenis elemen yang dipertimbangkan untuk Largest Contentful Paint adalah:
- Elemen
<img>
(waktu presentasi frame pertama digunakan untuk konten animasi seperti GIF atau PNG animasi) - Elemen
<image>
di dalam elemen<svg>
- elemen
<video>
(waktu pemuatan gambar poster atau waktu presentasi frame pertama untuk video yang digunakan—mana saja yang lebih awal) - Elemen dengan gambar latar yang dimuat menggunakan fungsi
url()
, (bukan gradien CSS) - Elemen tingkat blok yang berisi node teks atau turunan elemen teks tingkat inline lainnya.
Perhatikan bahwa pembatasan elemen ke kumpulan terbatas ini dilakukan secara sengaja agar semuanya tetap sederhana di awal. Elemen tambahan (seperti dukungan <svg>
lengkap) dapat ditambahkan di masa mendatang seiring dengan semakin banyaknya riset yang dilakukan.
Selain hanya mempertimbangkan beberapa elemen, pengukuran LCP menggunakan heuristik untuk mengecualikan elemen tertentu yang cenderung dilihat pengguna sebagai "tidak konten". Untuk browser berbasis Chromium, ini mencakup:
- Elemen dengan opasitas 0, yang tidak terlihat oleh pengguna
- Elemen yang menutupi area tampilan penuh, yang kemungkinan dianggap sebagai latar belakang, bukan konten
- Gambar placeholder atau gambar lain dengan entropi rendah, yang kemungkinan tidak mencerminkan konten sebenarnya dari halaman
Browser kemungkinan akan terus meningkatkan heuristik ini untuk memastikan kami memenuhi ekspektasi pengguna tentang elemen berisi terbesar.
Heuristik "kontenful" ini mungkin berbeda dengan yang digunakan oleh First Contentful Paint (FCP), yang mungkin mempertimbangkan beberapa elemen ini, seperti gambar placeholder atau gambar area pandang penuh, meskipun jika elemen tersebut tidak memenuhi syarat untuk menjadi kandidat LCP. Meskipun keduanya menggunakan "contentful" pada namanya, tujuan metrik ini berbeda. FCP mengukur saat konten apa pun ditampilkan di layar dan LCP saat konten utama ditampilkan sehingga LCP dimaksudkan untuk lebih selektif.
Bagaimana cara menentukan ukuran elemen?
Ukuran elemen yang dilaporkan untuk LCP biasanya adalah ukuran yang terlihat oleh pengguna dalam area pandang. Jika elemen diperluas ke luar area pandang, atau jika salah satu elemen terpotong atau memiliki overflow yang tidak terlihat, bagian tersebut tidak diperhitungkan dalam ukuran elemen.
Untuk elemen gambar yang telah diubah ukurannya dari ukuran intrinsik, ukuran yang dilaporkan adalah ukuran yang terlihat atau ukuran intrinsik, mana saja yang lebih kecil.
Untuk elemen teks, LCP hanya mempertimbangkan persegi panjang terkecil yang dapat berisi semua node teks.
Untuk semua elemen, LCP tidak mempertimbangkan margin, padding, atau batas yang diterapkan menggunakan CSS.
Kapan LCP dilaporkan?
Halaman web sering kali dimuat secara bertahap, dan akibatnya, elemen terbesar pada halaman mungkin berubah.
Untuk menangani potensi perubahan ini, browser mengirimkan PerformanceEntry
dari jenis largest-contentful-paint
yang mengidentifikasi elemen konten terbesar segera setelah browser merender frame pertama. Namun, setelah merender frame berikutnya, elemen ini akan mengirimkan PerformanceEntry
lain setiap kali elemen konten terbesar berubah.
Misalnya, di halaman dengan teks dan gambar hero, browser mungkin awalnya hanya merender teks—pada saat itu browser akan mengirimkan entri largest-contentful-paint
yang properti element
-nya kemungkinan akan mereferensikan <p>
atau <h1>
. Kemudian, setelah gambar hero selesai dimuat, entri largest-contentful-paint
kedua akan dikirim dan properti element
-nya akan mereferensikan <img>
.
Elemen hanya dapat dianggap sebagai elemen konten terbesar setelah dirender dan terlihat oleh pengguna. Gambar yang belum dimuat tidak dianggap "dirender". Node teks juga tidak menggunakan font web selama periode pemblokiran font. Dalam kasus tersebut, elemen yang lebih kecil mungkin dilaporkan sebagai elemen konten terbesar, tetapi segera setelah elemen yang lebih besar selesai dirender, PerformanceEntry
lain akan dibuat.
Selain gambar dan font yang dimuat terlambat, halaman dapat menambahkan elemen baru ke DOM saat konten baru tersedia. Jika salah satu elemen baru ini lebih besar dari elemen konten terbesar sebelumnya, PerformanceEntry
baru juga akan dilaporkan.
Jika elemen contentful terbesar dihapus dari area pandang, atau bahkan dari DOM, elemen tersebut tetap menjadi elemen contentful terbesar kecuali jika elemen yang lebih besar dirender.
Browser akan berhenti melaporkan entri baru segera setelah pengguna berinteraksi dengan halaman (melalui ketukan, scroll, atau penekanan tombol), karena interaksi pengguna sering kali mengubah apa yang terlihat oleh pengguna (terutama saat men-scroll).
Untuk tujuan analisis, Anda hanya boleh melaporkan PerformanceEntry
yang terakhir dikirim ke layanan analisis.
Waktu pemuatan versus waktu render
Untuk alasan keamanan, stempel waktu render gambar tidak ditampilkan untuk gambar lintas origin yang tidak memiliki header Timing-Allow-Origin
. Sebaliknya, hanya waktu pemuatannya yang diekspos (karena ini sudah diekspos melalui banyak API web lainnya).
Hal ini dapat menyebabkan situasi yang tampaknya tidak mungkin, yaitu LCP dilaporkan oleh API web lebih awal daripada FCP. Hal ini tidak benar, tetapi hanya muncul karena pembatasan keamanan ini.
Jika memungkinkan, sebaiknya tetap tetapkan header Timing-Allow-Origin
, sehingga metrik Anda akan lebih akurat.
Bagaimana perubahan ukuran dan tata letak elemen ditangani?
Agar overhead performa penghitungan dan pengiriman entri performa baru tetap rendah, perubahan pada ukuran atau posisi elemen tidak akan menghasilkan kandidat LCP baru. Hanya ukuran dan posisi awal elemen di area pandang yang dipertimbangkan.
Artinya, gambar yang awalnya dirender di luar layar, lalu bertransisi di layar mungkin tidak dilaporkan. Hal ini juga berarti elemen yang awalnya dirender di area pandang yang kemudian didorong ke bawah, di luar tampilan akan tetap melaporkan ukuran awal dalam area pandang.
Contoh
Berikut beberapa contoh kapan Largest Contentful Paint terjadi di beberapa situs populer:
Pada kedua linimasa di atas, elemen terbesar akan berubah saat konten dimuat. Pada contoh pertama, konten baru ditambahkan ke DOM dan hal ini mengubah elemen mana yang terbesar. Pada contoh kedua, tata letak berubah dan konten yang sebelumnya terbesar dihapus dari area pandang.
Meskipun konten yang dimuat lambat sering kali lebih besar dari konten yang sudah ada di halaman, hal ini tidak selalu terjadi. Dua contoh berikutnya menunjukkan LCP yang terjadi sebelum halaman dimuat sepenuhnya.
Pada contoh pertama, logo Instagram dimuat relatif lebih awal dan tetap menjadi elemen terbesar meskipun konten lain ditampilkan secara bertahap. Pada contoh halaman hasil Google Penelusuran, elemen terbesar adalah paragraf teks yang ditampilkan sebelum gambar atau logo selesai dimuat. Karena semua gambar lebih kecil dari paragraf ini, paragraf ini tetap menjadi elemen terbesar selama proses pemuatan.
Cara mengukur LCP
LCP dapat diukur di lab atau di lapangan, dan tersedia di alat berikut:
Alat kolom
- Laporan Pengalaman Pengguna Chrome
- PageSpeed Insights
- Search Console (laporan Core Web Vitals)
- Library JavaScript
web-vitals
Alat lab
Mengukur LCP di JavaScript
Untuk mengukur LCP di JavaScript, Anda dapat menggunakan Largest Contentful Paint API. Contoh berikut menunjukkan cara membuat PerformanceObserver
yang memproses entri largest-contentful-paint
dan mencatatnya ke konsol.
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
console.log('LCP candidate:', entry.startTime, entry);
}
}).observe({type: 'largest-contentful-paint', buffered: true});
Dalam contoh di atas, setiap entri largest-contentful-paint
yang dicatat dalam log mewakili kandidat LCP saat ini. Secara umum, nilai startTime
dari entri terakhir yang dikeluarkan adalah nilai LCP—tetapi, hal ini tidak selalu terjadi. Tidak semua entri largest-contentful-paint
valid untuk mengukur LCP.
Bagian berikut mencantumkan perbedaan antara laporan API dan cara penghitungan metrik.
Perbedaan antara metrik dan API
- API akan mengirimkan entri
largest-contentful-paint
untuk halaman yang dimuat di tab latar belakang, tetapi halaman tersebut harus diabaikan saat menghitung LCP. - API akan terus mengirim entri
largest-contentful-paint
setelah halaman berada di latar belakang, tetapi entri tersebut harus diabaikan saat menghitung LCP (elemen hanya dapat dipertimbangkan jika halaman berada di latar depan sepanjang waktu). - API tidak melaporkan entri
largest-contentful-paint
saat halaman dipulihkan dari cache kembali/maju, tetapi LCP harus diukur dalam kasus ini karena pengguna mengalaminya sebagai kunjungan halaman yang berbeda. - API tidak mempertimbangkan elemen dalam iframe, tetapi metrik melakukannya karena elemen tersebut merupakan bagian dari pengalaman pengguna halaman. Di halaman dengan LCP dalam iframe—misalnya gambar poster pada video tersemat—hal ini akan ditampilkan sebagai perbedaan antara CrUX dan RUM. Untuk mengukur LCP dengan benar, Anda harus mempertimbangkannya. Sub-frame dapat menggunakan API untuk melaporkan entri
largest-contentful-paint
ke frame induk untuk agregasi. - API mengukur LCP dari awal navigasi, tetapi untuk halaman yang dipra-render, LCP harus diukur dari
activationStart
karena sesuai dengan waktu LCP yang dialami pengguna.
Daripada menghafal semua perbedaan halus ini, developer dapat menggunakan library JavaScript web-vitals
untuk mengukur LCP, yang menangani perbedaan ini untuk Anda (jika memungkinkan—perhatikan bahwa masalah iframe tidak tercakup):
import {onLCP} from 'web-vitals';
// Measure and log LCP as soon as it's available.
onLCP(console.log);
Lihat kode sumber untuk onLCP()
guna mengetahui contoh lengkap cara mengukur LCP di JavaScript.
Bagaimana jika elemen terbesar bukan yang paling penting?
Dalam beberapa kasus, elemen (atau beberapa elemen) yang paling penting pada halaman tidak sama dengan elemen terbesar, dan developer mungkin lebih tertarik untuk mengukur waktu render elemen lain ini. Hal ini dapat dilakukan menggunakan Element Timing API, seperti yang dijelaskan dalam artikel tentang metrik kustom.
Cara meningkatkan LCP
Panduan lengkap tentang mengoptimalkan LCP tersedia untuk memandu Anda melalui proses identifikasi waktu LCP di kolom dan menggunakan data lab untuk melihat perincian dan mengoptimalkannya.
Referensi lainnya
- Pelajaran yang dipetik dari pemantauan performa di Chrome oleh Annie Sullivan di performance.now() (2019)
Log perubahan
Terkadang, bug ditemukan di API yang digunakan untuk mengukur metrik, dan terkadang di definisi metrik itu sendiri. Oleh karena itu, terkadang perubahan harus dilakukan, dan perubahan ini dapat muncul sebagai peningkatan atau regresi dalam laporan dan dasbor internal Anda.
Untuk membantu Anda mengelolanya, semua perubahan pada penerapan atau definisi metrik ini akan ditampilkan di Log Perubahan ini.
Jika ada masukan untuk metrik ini, Anda dapat memberikannya di grup Google untuk masukan web-vitals-feedback.