Setiap Optimasi di Balik Skor Lighthouse yang Sempurna

Saya menjalankan Lighthouse di situs saya secara terus-menerus. Skornya tetap di angka 100 pada setiap pengujian lokal dan 100 pada Real Experience Score milik Vercel.

Skor-skor ini tidak didapat dari daftar periksa (checklist) umum. Saya mencapainya dengan memindahkan beban kerja dari browser ke tahap build.

Inilah cara tepat bagaimana saya melakukannya.

Pindahkan beban kerja ke waktu build

Kebanyakan panduan menyarankan Anda untuk melakukan lazy-load pada segalanya. Saya lebih memilih untuk melakukan prerender. Saya menggunakan TanStack Start dengan fitur prerendering yang diaktifkan.

Hal ini mengubah seluruh situs menjadi HTML statis selama proses build. Browser tidak perlu mengeksekusi JavaScript yang berat hanya untuk menampilkan halaman pertama. HTML sudah tersedia saat pengguna menekan enter.

Hitung logika kompleks sebelumnya

Beranda saya memiliki peta dunia dengan 5.000 titik. Biasanya, sebuah library akan memparsing GeoJSON dan menjalankan perhitungan matematika pada main thread. Hal ini memblokir halaman selama 1.000ms.

Saya mengatasi ini dengan memindahkan perhitungan matematika ke skrip build.

  • Saya menghasilkan satu string SVG path untuk seluruh 5.000 titik tersebut.
  • Satu path jauh lebih cepat untuk dirender oleh browser daripada 5.000 lingkaran terpisah.
  • Saya menghitung tabel pencarian koordinat (lookup tables) sebelumnya sehingga browser tidak perlu melakukan perhitungan matematika sama sekali saat runtime.

Penundaan 1.000ms tersebut berubah menjadi satu kali proses paint yang instan.

Optimalkan pemuatan font

Saya menggunakan rel="preload" untuk font utama saya.

Kesalahan umum adalah melupakan atribut crossOrigin. Jika Anda melewatkannya, browser akan mengambil font tersebut dua kali. Ini merusak Largest Contentful Paint (LCP) Anda. Saya hanya melakukan preload pada tiga font yang digunakan di bagian atas halaman (above the fold).

Gunakan alat yang tepat untuk animasi

Saya menggunakan SMIL untuk animasi denyut (pulse) sederhana pada penanda peta saya. Ini lebih ringan daripada menggunakan React state untuk menjalankan loop animasi. Hal ini memungkinkan browser menangani pekerjaan tersebut pada compositor thread.

Untuk path yang kompleks, saya menggunakan motion. Saya menjaganya tetap sederhana. Saya melakukan animasi sekali saat mount dan menghindari mendengarkan (listening) posisi scroll.

Tetap gunakan vektor dan WebP

Jika itu adalah logo atau bentuk, gunakan SVG. Jika itu adalah foto, gunakan WebP. Ini menjaga ukuran file tetap rendah dan mencegah pergeseran tata letak (layout shifts).

Hindari over-engineering

Saya tidak menggunakan image CDN. Saya tidak menggunakan code-splitting yang kompleks. Situs saya kecil, jadi splitting di tingkat rute (route-level splitting) sudah cukup.

Skor sempurna bisa menjadi metrik kesenangan semata (vanity metric). Tujuan sebenarnya adalah mengukur performa Anda dan memindahkan sebanyak mungkin beban kerja menjauh dari perangkat pengguna.

Portofolio Saya: brodin.dev

Kode sumber: github.com/NathanBrodin/Portfolio

Prerendering TanStack Start: tanstack.com/start

Paper Shaders: shaders.paper.design

Postingan lengkap: https://dev.to/nathan-brodin/every-optimization-behind-a-perfect-lighthouse-score-283n