Cara Optimasi Core Web Vitals
Core Web Vitals adalah seperangkat metrik yang digunakan Google untuk mengukur pengalaman nyata pengunjung di situs Anda. Metrik ini diperkenalkan sebagai sinyal peringkat pada tahun 2021 dan tetap menjadi salah satu proksi kualitas halaman yang paling jelas bagi mesin pencari. Jika halaman Anda lambat dimuat, lambat merespons, atau melompat-lompat saat dirender, Anda akan kehilangan peringkat sekaligus pendapatan.
Tiga metrik yang membentuk Core Web Vitals adalah LCP (Largest Contentful Paint), INP (Interaction to Next Paint), dan CLS (Cumulative Layout Shift). Masing-masing mengukur bagian berbeda dari pengalaman memuat dan berinteraksi. Panduan ini menjelaskan apa arti setiap metrik, cara mengukurnya secara akurat, dan perbaikan spesifik yang benar-benar efektif.
Memahami Tiga Core Web Vitals
Sebelum mengoptimalkan apa pun, Anda harus tahu apa yang Anda optimalkan. Ketiga metrik ini mengukur hal yang berbeda dan tidak saling tumpang tindih.
Largest Contentful Paint (LCP)
LCP mengukur waktu sejak halaman mulai dimuat hingga elemen terbesar yang terlihat selesai dirender. Elemen tersebut biasanya berupa gambar hero, judul, atau poster video besar. Browser melaporkan LCP setiap kali elemen terbesar baru muncul, sehingga nilai akhir adalah waktu render elemen terbesar yang menang.
Toleransinya sederhana. LCP yang baik adalah 2,5 detik atau kurang, diukur pada persentil ke-75 dari pemuatan halaman. Nilai antara 2,5 dan 4,0 detik perlu diperbaiki, dan di atas 4,0 detik dianggap buruk. Karena LCP diukur pada persentil ke-75, Anda mengoptimalkan untuk mayoritas pengguna nyata, bukan untuk koneksi tercepat yang mungkin.
Empat penyebab paling umum LCP lambat adalah waktu respons server yang lambat, sumber daya render-blocking, pemuatan gambar yang lambat, dan rendering sisi klien yang lambat. Masing-masing memiliki perbaikan tersendiri, dan perbaikannya saling memperkuat: menghemat beberapa ratus milidetik dari respons server membantu semua metrik lainnya juga.
Interaction to Next Paint (INP)
INP menggantikan First Input Delay (FID) sebagai metrik interaksi pada Maret 2024. Tidak seperti FID yang hanya mengukur interaksi pertama, INP mengukur latensi setiap interaksi yang terjadi selama umur halaman, termasuk klik, sentuhan, dan penekanan tombol. Nilai yang dilaporkan adalah interaksi terburuk yang bukan pencilan (outlier).
INP yang baik adalah 200 milidetik atau kurang. Metrik ini didominasi oleh kerja main thread: JavaScript yang menjalankan tugas panjang, event handler berat, dan layout thrashing. Cara paling efektif untuk memperbaiki INP adalah menjaga main thread tetap bebas, yang biasanya berarti mengirim lebih sedikit JavaScript dan memecah tugas panjang.
Cumulative Layout Shift (CLS)
CLS mengukur seberapa besar tata letak halaman bergeser selama seluruh umur halaman, dari pemuatan awal hingga scroll dan interaksi. Skornya adalah jumlah semua pergeseran tata letak yang tidak terduga, dihitung sebagai jarak pergeseran dikali fraksi viewport yang terpengaruh.
Skor CLS yang baik adalah 0,1 atau kurang. Pergeseran tata letak hampir selalu disebabkan oleh konten yang disuntikkan ke halaman setelah konten di sekitarnya sudah ditata. Gambar tanpa dimensi eksplisit, iklan yang disuntikkan secara dinamis, dan font yang dimuat terlambat adalah penyebab klasik.
Mengukur Core Web Vitals
Anda tidak dapat memperbaiki apa yang tidak dapat Anda ukur. Untungnya, mengukur Core Web Vitals kini lebih mudah daripada sebelumnya, dan Anda harus menggunakan lebih dari satu alat karena masing-masing memberi sudut pandang berbeda terhadap masalah.
Data Field vs. Data Lab
Data field berasal dari pengguna nyata melalui Chrome UX Report (CrUX) dan mewakili apa yang sebenarnya dialami pengunjung di perangkat dan koneksi nyata. Data lab berasal dari lingkungan terkontrol seperti Lighthouse atau PageSpeed Insights dan mewakili perilaku halaman saat dimuat dengan cara yang dapat diprediksi. Anda membutuhkan keduanya. Data field memberi tahu apakah Anda punya masalah nyata; data lab memberi tahu di mana harus mencari.
Alat seperti Lighthouse dan PageSpeed Insights sangat cocok untuk diagnosis awal karena memecah timeline pemuatan menjadi audit. Misalnya, laporan Lighthouse memberi tahu Anda sumber daya mana yang render-blocking, seberapa besar setiap gambar, dan berapa banyak waktu main thread yang dikonsumsi setiap skrip.
Mengukur Lokal dengan Lighthouse
Lighthouse tersedia langsung di Chrome DevTools dan sebagai alat CLI, menjadikannya cara tercepat untuk mendapatkan baseline lab. Untuk mengukur halaman secara lokal, buka halaman, tekan F12 untuk membuka DevTools, dan pindah ke panel Lighthouse. Pilih kategori yang Anda butuhkan (Performance adalah yang penting untuk Core Web Vitals) dan jalankan audit. Laporan membutuhkan sekitar 30 detik dan menghasilkan skor 0 hingga 100 beserta daftar peluang yang terperinci.
Ingat bahwa hasil Lighthouse lokal mencerminkan kondisi mesin dan jaringan tempat Anda menguji. Jalankan beberapa kali dan gunakan median, serta pilih profil emulasi mobile karena itulah yang digunakan Google untuk peringkat.
Data Field dengan Library web-vitals
Cara paling akurat untuk mengumpulkan data field adalah dengan mengumpulkannya sendiri. Google menyediakan library JavaScript web-vitals, yang dapat dimuat dengan satu tag script. Library ini mengekspos tiga metrik utama plus beberapa metrik sekunder, dan dapat mengirim hasil ke backend analytics mana pun.
Implementasi minimalnya seperti ini:
<script src="https://unpkg.com/web-vitals"></script>
<script>
webVitals.onLCP((metric) => console.log('LCP', metric.value));
webVitals.onINP((metric) => console.log('INP', metric.value));
webVitals.onCLS((metric) => console.log('CLS', metric.value));
</script>
Setelah mengumpulkan pengukuran pengguna nyata, Anda dapat membandingkannya dengan alat web-vitals-calculator di situs ini untuk mengonversi nilai mentah menjadi skor persentil dan memastikan apakah Anda lulus penilaian Core Web Vitals.
Mengoptimalkan LCP
LCP adalah metrik dengan bagian yang paling banyak bergerak, sehingga paling diuntungkan oleh pendekatan sistematis. Mulai dari server, lalu perbaiki sumber daya, lalu optimalkan elemen terbesar itu sendiri.
Perbaiki Waktu Respons Server
20 hingga 50 persen pertama dari LCP sering kali hanya waktu yang dibutuhkan server untuk mengirim byte pertama dokumen HTML, yang dikenal sebagai TTFB. TTFB yang lambat membuat setiap optimasi berikutnya kurang efektif, karena browser tidak dapat mulai mengurai atau mengambil sumber daya hingga HTML tiba.
Perbaikan standarnya adalah page caching, optimasi query database, dan menghapus middleware lambat atau bootstrap framework. Untuk aplikasi PHP, pastikan Anda menggunakan opcode caching dan cache konfigurasi aktif, karena framework yang membaca ulang setiap file konfigurasi pada setiap request membuang ratusan milidetik. Anda juga harus mengompresi respons dengan gzip atau brotli agar HTML tiba lebih cepat.
Hapus Sumber Daya Render-Blocking
Browser tidak dapat merender apa pun hingga selesai mengambil dan mengurai CSS dan JavaScript render-blocking di dalam <head>. Setiap stylesheet render-blocking adalah satu round trip tambahan pada jalur kritis Anda. Dua strategi utamanya adalah inline critical CSS dan menunda sisanya.
Mulailah dengan mengidentifikasi CSS yang benar-benar dibutuhkan untuk render pertama. Itu biasanya mencakup tata letak header dan hero, tipografi, serta warna elemen terbesar. Inline CSS tersebut langsung ke <head>, lalu muat stylesheet lengkap dengan rel="preload" dan onload agar diterapkan secara asinkron tanpa memblokir first paint.
Untuk JavaScript, defaultnya harus defer untuk skrip yang berjalan saat load dan import() dinamis untuk kode yang hanya dibutuhkan setelah interaksi. Bundler modern seperti Vite dan webpack dapat memecah JavaScript Anda menjadi banyak chunk kecil yang dimuat sesuai kebutuhan, mengurangi kerja blocking saat startup.
Optimalkan Gambar Terbesar
Jika elemen LCP Anda adalah gambar, pengirimannya berdampak langsung pada metrik. Langkah pertama adalah memastikan gambar berukuran tepat untuk viewport: menyajikan gambar hero selebar 3000 piksel ke ponsel yang hanya menampilkan 600 piksel membuang bandwidth dan menambah ratusan milidetik pada LCP.
Tetapkan atribut width dan height eksplisit pada setiap gambar agar browser dapat menyediakan ruang, tambahkan fetchpriority="high" pada gambar LCP agar diambil sebelum sumber daya lain, dan gunakan format modern seperti WebP dan AVIF yang jauh lebih kecil daripada JPEG dan PNG. Anda dapat menggunakan alat image-optimizer di situs ini untuk mengompresi dan mengubah ukuran gambar tanpa kehilangan kualitas yang terlihat.
Terakhir, pastikan gambar tidak dimuat dengan lazy loading. Atribut loading="lazy" bagus untuk gambar di bawah fold, tetapi dapat menunda gambar LCP yang berada di atas fold. Secara eksplisit jangan gunakan lazy loading untuk gambar hero dan pertimbangkan untuk me-preload:
<img src="hero.webp" width="1200" height="675" fetchpriority="high" alt="Hero">
Kurangi Client-Side Rendering
Jika elemen LCP dirender oleh JavaScript alih-alih ada di HTML awal, browser harus mengunduh, mengurai, dan mengeksekusi JavaScript sebelum elemen itu bisa ada. Ini cara terberat untuk merender LCP. Perbaikannya adalah merender elemen LCP di sisi server, sehingga sudah ada di dokumen HTML awal, dan menggunakan JavaScript hanya untuk meningkatkan setelahnya.
Ini adalah pola umum pada aplikasi React, Vue, dan Svelte. Jika konten hero halaman Anda dihasilkan di sisi klien, pertimbangkan untuk beralih ke server-side rendering atau static generation untuk halaman tersebut, atau minimal pre-render konten penting di atas fold.
Mengoptimalkan INP
INP didominasi oleh kerja main thread, sehingga playbook optimasinya hampir seluruhnya tentang JavaScript.
Kirim Lebih Sedikit JavaScript
Cara paling andal untuk memperbaiki INP adalah mengirim lebih sedikit JavaScript sejak awal. Setiap byte JavaScript yang dimuat di halaman adalah potensi kerja main thread, dan setiap skrip pihak ketiga berisiko menjadi tugas panjang yang memblokir interaksi. Audit bundle Anda dan hapus library yang tidak terpakai, ganti library animasi berat dengan transform CSS, dan pilih fitur platform asli daripada polyfill.
Tree-shaking dan code splitting adalah dua fitur bundler yang membuat ini praktis. Tree-shaking menghapus ekspor yang tidak terpakai dari dependensi Anda, dan code splitting membuat chunk kecil yang hanya dimuat saat dibutuhkan. Anda juga harus menunda skrip pihak ketiga jika memungkinkan: analytics, widget chat, dan embed sosial jarang perlu berjalan saat pemuatan halaman.
Pecah Tugas Panjang
Bahkan dengan JavaScript lebih sedikit, satu tugas panjang pun dapat memblokir interaksi selama ratusan milidetik. Browser memperlakukan tugas lebih dari 50 milidetik sebagai long task, dan itu adalah penyebab langsung INP yang buruk. Perbaikannya adalah memecah pekerjaan menjadi potongan yang lebih kecil dan memberi jalan ke main thread di antaranya.
Teknik paling sederhana adalah await new Promise(resolve => setTimeout(resolve, 0)) di antara potongan pekerjaan, yang memberi jalan ke main thread. Pendekatan yang lebih canggih menggunakan requestIdleCallback untuk pekerjaan yang tidak mendesak dan API scheduler.yield() asli jika tersedia. Tujuannya sama: jangan pernah memblokir main thread lebih dari beberapa milidetik sekaligus.
Hindari Layout Thrashing
Layout thrashing terjadi ketika JavaScript membaca properti tata letak (seperti offsetWidth) lalu menulis ke DOM, memaksa browser menghitung ulang tata letak berulang kali. Membaca properti tata letak setelah penulisan DOM mahal karena browser harus menghitung tata letak secara sinkron sebelum membaca dapat kembali.
Kelompokkan baca dan tulis Anda. Baca semua nilai tata letak yang Anda butuhkan terlebih dahulu, lalu lakukan semua penulisan. Jika Anda menganimasikan, pilih Web Animations API atau transform CSS serta opacity, yang ramah kompositor dan tidak memicu tata letak.
Mengoptimalkan CLS
CLS sering kali menjadi metrik yang paling mudah diperbaiki karena penyebabnya sudah dikenal dengan solusi sederhana.
Sediakan Ruang untuk Gambar dan Iklan
Setiap gambar, video, dan iklan tertanam harus memiliki dimensi eksplisit yang disediakan di tata letak. Untuk gambar, selalu tetapkan atribut width dan height; browser modern menghormatinya dan menyediakan ruang, mencegah tata letak bergeser saat gambar dimuat. Untuk gambar responsif, atribut tersebut bekerja bersama srcset dan CSS aspect-ratio untuk menyediakan ruang yang benar.
Iklan adalah masalah khusus karena ukurannya ditentukan oleh jaringan iklan saat runtime. Sediakan slot dengan tinggi tetap untuk wadah iklan, bahkan jika iklan mengisi ukuran yang lebih kecil. Jika harus mendukung beberapa ukuran iklan, sediakan yang terbesar dan pusatkan iklan sebenarnya di dalam slot.
Muat Font Tanpa Bergeser
Web font adalah penyebab CLS klasik karena browser awalnya merender teks dengan font cadangan lalu menggantinya dengan web font saat dimuat, mengubah ukuran teks. Perbaikannya adalah menyediakan metrik web font secara eksplisit. Gunakan font-display: swap yang dikombinasikan dengan size-adjust, ascent-override, dan descent-override agar font cadangan menempati ruang yang sama dengan web font.
Anda juga harus membuat subset font sehingga hanya glyph yang benar-benar Anda gunakan yang diunduh. Icon font lengkap bisa berbobot hampir seratus kilobyte, tetapi subset dengan hanya ikon yang digunakan di situs Anda jauh lebih kecil, yang mempercepat pemuatan sekaligus mengurangi peluang font swap terlambat. Tetapkan nilai font-size eksplisit pada teks daripada mengandalkan perbedaan line-height alami antar font.
Hindari Menyisipkan Konten di Atas Fold
Penambahan DOM di atas fold setelah render awal menyebabkan pergeseran tata letak. Penyebab paling umum adalah banner cookie, prompt notifikasi, dan interstisial yang masuk dari atas. Render mereka di ruang yang disediakan atau di dalam overlay yang tidak mendorong konten.
Jika harus menyisipkan konten secara dinamis, sediakan ruangnya terlebih dahulu dengan elemen placeholder yang memiliki tinggi yang diharapkan, atau gunakan overlay posisi tetap agar konten halaman di bawahnya tidak bergerak.
Membangun Kebiasaan Pengukuran
Core Web Vitals bukan perbaikan sekali jalan; nilainya berubah seiring Anda menambah fitur. Praktik terbaiknya adalah menambahkan library web-vitals ke situs produksi Anda dan mengirim hasil ke analytics, lalu siapkan alert untuk nilai persentil ke-75 agar Anda tahu saat deployment baru merusak performa.
Setiap optimasi dalam panduan ini saling memperkuat. Memperbaiki waktu respons server membantu LCP, mengirim lebih sedikit JavaScript membantu INP, dan menyediakan ruang membantu CLS. Ukur sebelum dan sesudah setiap perubahan dengan alat seperti web-vitals-calculator atau PageSpeed Insights, dan ingat bahwa tujuannya adalah persentil ke-75 untuk pengguna nyata, bukan hasil tercepat di mesin lokal Anda.