Tiga metrik dan angka yang harus dikejar
Core Web Vitals adalah sekumpulan ukuran dari Google yang menilai pengalaman nyata orang saat membuka halaman. Ukurannya ada tiga.
LCP (Largest Contentful Paint) menghitung seberapa cepat elemen terbesar di layar selesai digambar. INP (Interaction to Next Paint) menghitung jeda antara pengunjung mengklik sesuatu dan layar berubah. CLS (Cumulative Layout Shift) menghitung seberapa banyak isi halaman bergeser sendiri selama memuat.
Ketiga ukuran itu bukan angka untuk dipamerkan di laporan. Ketiganya jadi sinyal peringkat di Google, dan yang lebih menentukan lagi, ketiganya yang memutuskan pengunjung bertahan atau pergi.
Ini angka ambangnya.
| Ukuran | Bagus | Perlu diperbaiki | Buruk |
|---|---|---|---|
| LCPLama muncul | 2,5 detik atau kurang | 2,5 sampai 4 detik | Di atas 4 detik |
| INPBerat disentuh | 200 milidetik atau kurang | 200 sampai 500 milidetik | Di atas 500 milidetik |
| CLSLoncat-loncat | 0,1 atau kurang | 0,1 sampai 0,25 | Di atas 0,25 |
Dua hal yang gampang terlewat dari tabel itu.
Pertama, penilaiannya di persentil ke-75. Artinya tiga dari empat pengunjung harus mendapat angka di bawah ambang, bukan rata-ratanya. Satu pengunjung dengan HP kencang tidak menutupi sepuluh pengunjung dengan HP biasa.
Kedua, mobile dan desktop dihitung sendiri-sendiri. Halaman yang hijau di desktop bisa merah di mobile, dan untuk kebanyakan bisnis lokal yang menentukan ya angka mobile.
Dari ketiganya, LCP yang paling sering tersandung hal di luar kode.
Elemen terbesar di layar biasanya gambar hero. Ukuran filenya memang menentukan, tapi jarak tempuhnya juga. Server di Jakarta menjawab pembaca di Makassar dengan penundaan yang tidak bisa dihapus dari sisi kode. Untuk memendekkan jarak itu ada content delivery network, dan kapan pemakaiannya sepadan kami hitung terpisah.
Halaman yang terasa lambat akan ditinggalkan sebelum sempat menjual apa pun. Ini yang selalu kami tekankan di jasa pembuatan website kami.
Yang berubah bukan rumus metriknya, tapi apa yang diukur. Sejak INP menggantikan FID pada 2024, penilaian tidak lagi berhenti di seberapa cepat halaman muncul. Yang ikut dihitung sekarang seberapa sigap halaman menjawab tiap kali disentuh, dan itu wilayah yang selama ini jarang disentuh pekerjaan optimasi.
Artikel ini bercerita dari sisi bagaimana kami menulisnya. Kalau yang Anda cari cara mencari penyebab website yang sudah terlanjur lambat, urutan pemeriksaannya kami tulis terpisah di kenapa website lambat.
INP mengubah cara kami berpikir
Dulu kami banyak mengejar LCP. Memperkecil gambar, menunda script, mendahulukan konten paling atas. Pekerjaan itu masih penting sampai sekarang.
Tapi INP menanyakan hal yang berbeda. Bukan seberapa cepat sesuatu datang, tapi seberapa sigap halaman menjawab waktu disentuh.
Bedanya kelihatan begini. LCP diukur satu kali di awal, sedangkan INP mengintip sepanjang kunjungan, tiap kali pengunjung mengklik, mengetuk, atau menekan tombol keyboard.
Nah, di sinilah letak masalahnya. Browser mengerjakan hampir semuanya di satu jalur yang sama, dan jalur itu juga yang melayani klik pengunjung. Kalau jalurnya sedang sibuk menghitung sesuatu, ketukan pengunjung harus antre.
Yang bikin jalur itu sibuk sering bukan fitur besar. Animasi yang memaksa browser mengukur ulang posisi elemen, daftar panjang yang dihitung ulang tiap frame, atau efek visual yang tampak sepele di layar desainer tapi mahal di HP kelas menengah.
Jadi pertanyaannya bergeser. Bukan lagi "berapa besar file ini", tapi "berapa banyak pekerjaan yang saya suruh browser lakukan".
Kenapa transform murah dan margin mahal
Untuk menampilkan satu frame, browser melewati beberapa tahap berurutan. Menghitung gaya yang berlaku, menghitung posisi dan ukuran tiap elemen, menggambar pikselnya, lalu menyusun lapisan-lapisannya jadi satu gambar utuh.
Tahap kedua itu yang mahal. Begitu satu elemen berubah lebar, browser harus memeriksa apakah elemen di sebelahnya ikut bergeser, lalu elemen berikutnya lagi.
Sekarang bandingkan dua animasi yang hasilnya terlihat identik di layar.
/* mahal: memaksa hitung ulang posisi tiap frame */
.kartu { transition: left 300ms; }
.kartu:hover { left: 20px; }
/* murah: cukup digeser saat penyusunan lapisan */
.kartu { transition: transform 300ms; }
.kartu:hover { transform: translateX(20px); }
Yang pertama menyentuh tahap perhitungan posisi di setiap frame. Yang kedua tidak, karena transform dan opacity bisa diselesaikan di tahap penyusunan lapisan, tanpa mengganggu perhitungan tata letak.
Kenapa ini penting? Karena untuk 60 frame per detik, browser cuma punya sekitar 16,7 milidetik menyiapkan satu frame. Jatah itu gampang sekali habis.
Ada satu lagi yang jarang disadari, dan ini soal JavaScript yang bersinggungan dengan CSS. Kalau kode Anda mengubah style sebuah elemen lalu langsung membaca ukurannya, browser terpaksa menghitung ulang tata letak saat itu juga, di tengah pekerjaan lain. Kalau pola itu ada di dalam loop, browser dipaksa mengulang perhitungan puluhan kali per detik.
Kami pernah melakukannya sendiri. Efek kursor kustom di situs ini dulu membaca posisi elemen di tiap frame, dan itu jalan terus walaupun perangkatnya layar sentuh yang tidak punya kursor sama sekali.
Kebiasaan CSS yang kami ubah
Beberapa kebiasaan yang sekarang jadi aturan main di studio.
- Animasi hanya pada properti murah. Gerakan dibatasi ke
transformdanopacity. Kalau sebuah efek tidak bisa dibuat dengan dua properti itu, biasanya efeknya memang tidak sepadan. - Efek yang jalan terus dikasih pagar. Animasi yang berputar tanpa henti dimatikan di perangkat sentuh lewat
matchMedia('(pointer:fine)'). Di HP efek itu tidak kelihatan, tapi tetap memakan CPU dan tetap mengganggu INP. - Guard
prefers-reduced-motionselalu ada. Pengunjung yang mengatur perangkatnya untuk mengurangi gerakan mendapat versi tanpa animasi, dan konten tetap tampil utuh. - Ruang dicadangkan sejak awal. Gambar dan media diberi dimensi atau
aspect-ratiosupaya tidak ada yang terdorong waktu asetnya datang. - Font di server sendiri. Satu file variable font per keluarga, dipanggil lewat
@font-facedenganfont-display:swap, tanpa koneksi ke domain lain. - Selector yang dangkal. Aturan yang bertumpuk dalam-dalam memaksa browser bekerja lebih keras di tiap perubahan, dan lebih susah dilacak waktu ada yang aneh.
Intinya tiap keputusan visual sekarang ditimbang dengan satu pertanyaan. Apa biayanya bagi performa, dan siapa yang membayarnya?
Kalau jawabannya "pengunjung dengan HP paling biasa", efeknya kami cari bentuk lain.
Jebakan yang dulu kami buat sendiri
Bagian ini agak memalukan, tapi justru paling berguna.
Situs ini punya animasi masuk. Elemen mulai dari opacity:0, lalu JavaScript menyalakannya begitu elemen itu masuk layar. Kelihatannya rapi, dan selama berbulan-bulan tidak ada yang merasa ada yang salah.
Ternyata pola itu punya dua lubang yang dua-duanya kami tabrak.
Lubang pertama, judul halaman jadi sandera JavaScript. Teks <h1> sudah ada di HTML, sudah terkirim di paket data pertama, sudah sampai di browser pengunjung. Lalu CSS kami sendiri yang menyuruh browser jangan menampilkannya dulu, sampai file JavaScript selesai jalan sekitar detik 2,9. Karena judul itu elemen terbesar di layar, angka LCP-nya ya ikut menunggu.
Lubang kedua, satu halaman jadi putih polos. Kode animasinya menyalakan elemen kalau minimal 12 persen bagiannya sudah terlihat. Aturan itu masuk akal untuk kartu dan gambar. Tapi waktu class yang sama dipasang di container artikel yang panjangnya ribuan piksel, 12 persen itu tidak pernah tercapai, karena layar pengunjung memang tidak sebesar itu. Isinya tetap opacity:0, dan pembaca cuma melihat halaman kosong.
Perbaikannya dua-duanya sederhana setelah tahu masalahnya.
- Judul dan isi halaman digambar langsung tanpa syarat. Animasinya tetap ada, cuma sekarang bentuknya menggeser posisi lewat
transform, bukan menahan tampilan lewatopacity. - Class animasi tidak lagi dipasang di container besar, cuma di elemen yang memang seukuran layar.
Pelajaran yang kami bawa dari kejadian itu satu kalimat saja. Animasi masuk yang dimulai dari kondisi tersembunyi membuat konten Anda bergantung pada JavaScript, dan konten yang bergantung pada JavaScript punya cara sendiri untuk gagal di situasi yang tidak Anda bayangkan.
Menyediakan ruang sebelum isinya datang
CLS mengukur hal yang paling sering dirasakan orang tapi paling jarang dilaporkan. Anda sedang membaca, lalu tulisannya melompat, dan jari Anda terlanjur menekan tombol yang salah.
Penyebabnya hampir selalu sama, yaitu ada sesuatu yang datang belakangan dan browser tidak tahu harus menyediakan ruang berapa.
Yang kami kerjakan untuk itu ada tiga.
- Tiap
<img>ditulis lengkap denganwidthdanheightaslinya. Ukuran tampil tetap diatur CSS, jadi tidak ada yang berubah secara visual. Yang berubah cuma browser sekarang tahu perbandingan sisinya sejak awal. - Wadah gambar diberi
aspect-ratio. Kartu artikel dan gambar studi kasus memakaiaspect-ratio:16/9denganobject-fit:cover, sehingga tinggi kotaknya sudah pasti bahkan sebelum gambarnya ada. - Elemen yang muncul belakangan dikasih tempat duduk. Banner, notifikasi, dan apa pun yang disisipkan JavaScript diletakkan di ruang yang sudah dicadangkan, bukan diselipkan di tengah teks yang sedang dibaca orang.
Waktu kami menyisir ulang situs ini, yang ketemu justru gambar-gambar kecil yang selama ini tidak dicurigai. Thumbnail di daftar artikel dan gambar di halaman studi kasus. Risikonya memang kecil karena wadahnya sudah punya aspect-ratio, tapi menuliskan dimensinya tetap lebih baik daripada berharap.
Prinsip yang kami pegang
Performa yang baik bukan hasil satu trik, tapi disiplin yang dijalankan terus. Tiga hal yang kami pegang.
- Bangun ringan sejak awal. Menambal di akhir selalu lebih mahal daripada tidak menambahkan bebannya sejak awal, dan hasilnya jarang sebagus itu.
- Ukur dengan data nyata. Skor simulasi berguna untuk menemukan arah, tapi yang menentukan tetap angka dari pengunjung sungguhan.
- Efek harus bisa mempertanggungjawabkan biayanya. Kalau sebuah animasi tidak menolong orang memahami apa yang terjadi di layar, animasi itu cuma ongkos.
Filosofi yang sama jadi fondasi layanan SEO kami, karena halaman cepat menang di Google maupun di mata pengunjung. Soal apa saja yang dinilai Google selain kecepatan, kami bahas di apa itu SEO.
Dan kalau angka Anda sudah bagus tapi halamannya tetap tidak kelihatan di hasil pencarian, biasanya urusannya bukan di performa. Itu cerita yang berbeda, dan ada di website tidak muncul di Google.
Pertanyaan Umum
Apa itu Core Web Vitals dan berapa angka yang harus dikejar?
Core Web Vitals adalah tiga ukuran dari Google yang menilai pengalaman nyata orang saat membuka halaman. LCP mengukur seberapa cepat elemen terbesar di layar selesai digambar, dan targetnya 2,5 detik atau kurang. INP mengukur jeda antara pengunjung mengklik sesuatu dan layar berubah, targetnya 200 milidetik atau kurang. CLS mengukur seberapa banyak isi halaman bergeser sendiri saat memuat, targetnya 0,1 atau kurang. Ketiganya dinilai pada persentil ke-75 kunjungan nyata, dan mobile dinilai terpisah dari desktop. Jadi angka yang benar-benar perlu dikejar adalah angka mobile, bukan angka desktop yang biasanya jauh lebih bagus.
Kenapa animasi CSS bisa bikin website terasa berat?
Karena tidak semua properti CSS sama biayanya. Menganimasikan width, height, top, left, atau margin memaksa browser menghitung ulang posisi elemen lain di setiap frame, dan perhitungan itu terjadi di thread yang sama dengan yang melayani klik pengunjung. Menganimasikan transform dan opacity berbeda, karena keduanya bisa dikerjakan di tahap compositing tanpa mengganggu perhitungan tata letak. Dengan target 60 frame per detik, browser cuma punya sekitar 16,7 milidetik untuk menyiapkan satu frame. Animasi yang memaksa perhitungan ulang tata letak gampang sekali melewati jatah itu, dan yang dirasakan pengunjung adalah halaman yang tersendat waktu di-scroll atau diklik.
Apakah skor PageSpeed 100 itu wajib?
Tidak. Skor PageSpeed datang dari Lighthouse, yang menjalankan halaman Anda satu kali di mesin simulasi, sementara yang dipakai Google untuk menilai halaman adalah data lapangan dari pengguna Chrome sungguhan selama 28 hari terakhir. Dua angka itu sering berbeda. Selisih 92 ke 100 hampir tidak terasa oleh pengunjung, sedangkan pekerjaan untuk mengejarnya bisa memakan berhari-hari dan kadang mengorbankan hal lain yang lebih berguna. Yang lebih layak dijadikan target adalah ketiga Core Web Vitals masuk zona hijau di data lapangan, khususnya di mobile.
Apa bedanya INP dan FID?
FID hanya mengukur interaksi pertama, dan cuma menghitung jeda sebelum browser mulai memproses interaksi itu. INP mengukur seluruh interaksi sepanjang kunjungan, dan menghitung sampai layar benar-benar berubah, bukan berhenti di awal pemrosesan. Karena itu INP jauh lebih jujur menggambarkan rasa berat yang dikeluhkan orang. INP resmi menggantikan FID sebagai anggota Core Web Vitals pada 2024. Kalau website Anda dulu lolos FID tapi sekarang merah di INP, bukan berarti ada yang rusak, cuma yang diukur memang berbeda.
Apakah menghapus semua animasi akan membuat website lebih cepat?
Belum tentu, dan biasanya tidak perlu sejauh itu. Yang membebani bukan animasinya, tapi properti apa yang dianimasikan dan kapan animasi itu jalan. Animasi yang hanya menggeser transform dan mengubah opacity, durasinya pendek, dan tidak jalan terus-menerus di latar belakang, biayanya sangat kecil. Yang perlu dibuang itu animasi yang memaksa perhitungan ulang tata letak, animasi yang berjalan tanpa henti walaupun tidak kelihatan, dan animasi masuk yang menyembunyikan konten sampai JavaScript selesai. Tambahkan juga guard prefers-reduced-motion supaya pengunjung yang memilih mengurangi gerakan tetap terlayani.