Core Web Vitals adalah tiga metrik pengalaman pengguna yang dipakai Google: LCP (seberapa cepat konten utama tampil, target ≤ 2,5 detik), INP (seberapa cepat halaman merespons interaksi, target ≤ 200 milidetik), dan CLS (seberapa stabil tata letak, target ≤ 0,1). Sebuah halaman dianggap lolos bila ketiganya masuk kategori "baik" pada persentil ke-75 kunjungan nyata. Sejak Maret 2024, INP resmi menggantikan FID sebagai metrik responsivitas.
Artikel ini membahas arti tiap metrik dan ambang batasnya, cara mengukur dengan PageSpeed Insights, CrUX, dan Chrome DevTools, lalu perbaikan konkret untuk situs Laravel dengan Bootstrap, yaitu tumpukan yang dipakai banyak developer di Indonesia.
Tiga metrik dan ambang batasnya
Ambang berikut berasal dari dokumentasi resmi di web.dev:
| Metrik | Mengukur | Baik | Perlu perbaikan | Buruk |
|---|---|---|---|---|
| LCP (Largest Contentful Paint) | Kecepatan tampil elemen konten terbesar | ≤ 2,5 s | 2,5–4 s | > 4 s |
| INP (Interaction to Next Paint) | Jeda dari interaksi sampai layar diperbarui | ≤ 200 ms | 200–500 ms | > 500 ms |
| CLS (Cumulative Layout Shift) | Pergeseran tata letak tak terduga | ≤ 0,1 | 0,1–0,25 | > 0,25 |
Penilaian dilakukan pada persentil ke-75, terpisah untuk perangkat mobile dan desktop. Artinya, setidaknya 75% kunjungan harus mendapat pengalaman "baik". Rata-rata yang bagus tidak cukup bila seperempat pengunjung Anda memakai ponsel lambat.
LCP
LCP mencatat waktu saat elemen terbesar di area layar pertama selesai dirender. Biasanya elemen ini berupa gambar hero, thumbnail artikel, atau blok judul besar. LCP dipengaruhi empat hal: waktu respons server (TTFB), keterlambatan sebelum resource mulai diunduh, durasi unduhan, dan waktu render.
INP
INP mengamati semua klik, ketukan, dan tekanan tombol keyboard selama halaman dibuka, lalu melaporkan salah satu interaksi terlama. Berbeda dengan FID yang hanya mengukur jeda interaksi pertama sebelum diproses, INP mengukur sampai frame berikutnya benar-benar tampil. Itu sebabnya situs yang lolos FID bisa saja gagal INP.
CLS
CLS menjumlahkan pergeseran tata letak yang tidak diawali interaksi pengguna. Contoh klasiknya: Anda hendak mengetuk tautan, lalu iklan atau gambar muncul di atasnya dan tautan bergeser ke bawah.
Cara mengukur: data lapangan vs data lab
Ada dua jenis data yang sering tertukar:
- Data lapangan (field data) berasal dari pengguna Chrome sungguhan melalui Chrome UX Report (CrUX). Data inilah yang dipakai untuk menilai Core Web Vitals, misalnya di laporan Search Console.
- Data lab berasal dari simulasi Lighthouse di satu perangkat dan jaringan tertentu. Berguna untuk debugging, tetapi bukan penilaian resmi.
PageSpeed Insights
Buka pagespeed.web.dev dan masukkan URL. Bagian atas menampilkan data lapangan dari CrUX bila situs Anda memiliki cukup trafik; bagian bawah adalah hasil lab Lighthouse beserta saran perbaikan. Data CrUX merupakan agregat 28 hari terakhir, sehingga perbaikan hari ini baru terlihat penuh beberapa minggu kemudian.
Lighthouse tidak bisa mengukur INP karena tidak ada interaksi nyata. Sebagai gantinya, perhatikan Total Blocking Time (TBT): TBT tinggi biasanya berarti JavaScript yang berat dan berpotensi menghasilkan INP buruk.
Search Console
Laporan Core Web Vitals di Search Console mengelompokkan URL dengan masalah serupa. Ini cara tercepat untuk melihat template mana (misalnya halaman artikel atau halaman kategori) yang bermasalah.
Chrome DevTools
Panel Performance di DevTools menampilkan nilai LCP, CLS, dan INP secara langsung saat Anda berinteraksi dengan halaman. Rekam sesi, lalu periksa elemen LCP, daftar layout shift, dan tugas panjang (long task) yang memblokir thread utama. Aktifkan throttling CPU dan jaringan agar kondisinya mendekati ponsel kelas menengah.
Mengukur sendiri dari pengunjung nyata
Untuk data yang lebih cepat dan terperinci daripada CrUX, gunakan pustaka web-vitals dari tim Chrome:
npm install web-vitals
import { onLCP, onINP, onCLS } from 'web-vitals';
function send(metric) {
const body = JSON.stringify({
name: metric.name,
value: metric.value,
rating: metric.rating,
page: location.pathname,
});
navigator.sendBeacon('/vitals', body);
}
onLCP(send);
onINP(send);
onCLS(send);
Simpan data tersebut di endpoint Laravel sederhana (jika belum terbiasa membuat route dan controller, lihat panduan belajar Laravel), lalu hitung persentil ke-75 per template halaman. Pastikan endpoint diberi rate limit.
Memperbaiki LCP di situs Laravel + Bootstrap
1. Percepat respons server (TTFB)
Jika HTML baru tiba setelah satu detik, LCP 2,5 detik hampir mustahil tercapai. Langkah dasar di produksi:
php artisan config:cache
php artisan route:cache
php artisan view:cache
composer install --no-dev --optimize-autoloader
Pastikan OPcache aktif di PHP, periksa query lambat dan N+1 (eager loading dengan with(), dan indeks yang tepat seperti dibahas di panduan belajar MySQL), dan pertimbangkan cache untuk halaman publik yang jarang berubah, misalnya hasil query artikel populer dengan Cache::remember(). Panduan menyiapkan server produksi ada di deploy Laravel ke VPS Nginx.
2. Jangan lazy-load gambar LCP, beri prioritas tinggi
Kesalahan umum adalah memasang loading="lazy" pada semua gambar, termasuk gambar hero. Gambar LCP harus dimuat secepat mungkin:
<img src="{{ $post->thumbnail_url }}"
alt="{{ $post->title }}"
width="1200" height="630"
fetchpriority="high"
class="img-fluid">
Gunakan loading="lazy" hanya untuk gambar di bawah layar pertama. Bila gambar LCP berada di CSS (misalnya background), browser baru menemukannya setelah CSS diunduh. Lebih baik gunakan tag <img> biasa, atau tambahkan <link rel="preload" as="image"> di <head>.
3. Kompres dan ubah ukuran gambar
Kirim gambar sesuai ukuran tampilan dan dalam format modern seperti WebP atau AVIF. Gunakan srcset agar ponsel tidak mengunduh gambar selebar desktop:
<img src="/img/hero-800.webp"
srcset="/img/hero-480.webp 480w, /img/hero-800.webp 800w, /img/hero-1200.webp 1200w"
sizes="(max-width: 768px) 100vw, 800px"
width="800" height="450" alt="..." fetchpriority="high">
4. Kurangi CSS dan JS yang memblokir render
Bootstrap lengkap berisi banyak komponen yang tidak Anda pakai. Jika memakai Vite, impor hanya bagian Sass yang dibutuhkan, atau gunakan PurgeCSS untuk membuang class yang tidak terpakai. Script yang tidak dibutuhkan untuk render awal beri atribut defer. Ingat bahwa @vite menghasilkan script bertipe module, yang secara bawaan sudah ditunda.
5. Font
Jika memakai Google Fonts, sertakan display=swap dan preconnect ke fonts.gstatic.com. Lebih baik lagi, host font sendiri dan muat hanya ketebalan yang benar-benar dipakai.
Memperbaiki INP
INP buruk hampir selalu disebabkan thread utama yang sibuk menjalankan JavaScript saat pengguna berinteraksi.
Berlangganan gratis. Artikel & tutorial coding terbaru langsung ke email kamu. Tanpa spam.
1. Audit script pihak ketiga
Widget chat, tag analytics ganda, pixel iklan, dan plugin sosial sering menjadi penyebab utama. Hapus yang tidak dipakai, muat yang tersisa dengan defer atau async, dan tunda widget berat sampai pengguna menggulir atau mengklik.
2. Pecah tugas panjang
Tugas JavaScript di atas 50 ms dianggap long task. Jika event handler melakukan banyak pekerjaan, perbarui tampilan dulu, lalu serahkan kembali kendali ke browser sebelum melanjutkan pekerjaan berat:
function yieldToMain() {
return new Promise(resolve => setTimeout(resolve, 0));
}
button.addEventListener('click', async () => {
button.classList.add('loading'); // umpan balik visual dulu
await yieldToMain(); // biarkan browser menggambar
await kirimDataBerat(); // pekerjaan berat setelahnya
});
3. Hati-hati dengan handler jQuery dan input
Banyak situs Bootstrap lama memasang handler jQuery berat pada event input, scroll, atau resize. Gunakan debounce untuk pencarian instan, hindari membaca dan menulis tata letak berulang dalam satu loop (layout thrashing), dan pertimbangkan menghapus jQuery bila hanya dipakai untuk sedikit fungsi.
4. Kurangi ukuran DOM
Halaman dengan ribuan elemen (misalnya tabel admin tanpa paginasi) membuat setiap pembaruan tampilan menjadi mahal. Gunakan paginasi di Laravel (paginate()) dan tampilkan data seperlunya.
Memperbaiki CLS
1. Selalu cantumkan width dan height pada gambar
Dengan atribut width dan height, browser bisa menghitung rasio dan mencadangkan ruang sebelum gambar diunduh. Class img-fluid Bootstrap tetap membuat gambar responsif, karena browser modern memakai kedua atribut tersebut untuk rasio aspek. Untuk thumbnail dengan rasio tetap, CSS aspect-ratio juga bisa dipakai.
2. Cadangkan ruang untuk iklan dan embed
Slot iklan yang diisi belakangan adalah sumber CLS paling umum di blog. Beri wadahnya tinggi minimum yang sesuai ukuran iklan yang biasa tampil:
.ad-slot {
min-height: 280px;
}
@media (min-width: 768px) {
.ad-slot { min-height: 90px; }
}
Untuk video YouTube atau peta, bungkus dengan helper rasio Bootstrap 5, misalnya <div class="ratio ratio-16x9">.
3. Jangan menyisipkan konten di atas konten yang sudah ada
Banner cookie, notifikasi, atau bar promosi yang didorong masuk dari atas akan menggeser seluruh halaman. Tampilkan sebagai overlay posisi fixed, atau cadangkan ruangnya sejak HTML pertama dirender.
4. Font yang berganti
Saat font kustom selesai dimuat, ukuran teks bisa berubah dan menggeser tata letak. Gunakan font fallback dengan metrik serupa, atau muat font lebih awal dengan preload.
Pergeseran yang terjadi dalam 500 ms setelah pengguna mengklik tidak dihitung dalam CLS. Jadi accordion atau dropdown Bootstrap yang dibuka pengguna umumnya aman.
Kesalahan umum
- Mengejar skor Lighthouse 100, padahal penilaian resmi memakai data lapangan.
- Lazy-load pada gambar LCP.
- Gambar tanpa width/height, terutama thumbnail di daftar artikel.
- Menambah script pihak ketiga tanpa mengukur dampaknya terhadap INP.
- Berharap angka di Search Console berubah sehari setelah perbaikan, padahal CrUX memakai jendela 28 hari.
Checklist Core Web Vitals
- TTFB rendah: cache config/route/view, OPcache, query efisien.
- Gambar LCP tanpa lazy-load, dengan
fetchpriority="high", terkompresi, dan responsif. - CSS Bootstrap dipangkas; JS tidak kritis ditunda.
- Script pihak ketiga diaudit; tidak ada long task di event handler.
- Semua gambar dan embed punya dimensi atau rasio; slot iklan punya tinggi minimum.
- Pantau data lapangan lewat Search Console, PageSpeed Insights, atau
web-vitals.
FAQ
Apakah Core Web Vitals faktor peringkat Google?
Ya, sebagai bagian dari sinyal pengalaman halaman. Namun relevansi dan kualitas konten tetap jauh lebih menentukan. Anggap Core Web Vitals sebagai pembeda ketika kualitas konten setara, dan sebagai perbaikan nyata bagi pengguna.
Kapan INP menggantikan FID?
INP menjadi Core Web Vital stabil dan menggantikan FID pada Maret 2024.
Mengapa PageSpeed Insights tidak menampilkan data lapangan untuk situs saya?
CrUX hanya menampilkan data untuk URL atau origin dengan jumlah kunjungan pengguna Chrome yang cukup. Untuk situs kecil, gunakan data lab dan ukur sendiri dengan pustaka web-vitals.
Skor Lighthouse saya 95, mengapa Search Console menyatakan gagal?
Lighthouse adalah simulasi satu kali, sedangkan Search Console memakai data pengunjung nyata selama 28 hari. Pengunjung dengan ponsel lambat dan jaringan buruk bisa menghasilkan angka yang jauh berbeda.
Apakah iklan AdSense memperburuk CLS?
Bisa, bila slot iklan tidak memiliki ruang yang dicadangkan. Beri wadah iklan tinggi minimum agar konten tidak bergeser ketika iklan dimuat.