Website lu bisa dapat skor bagus, bundle sudah dipangkas, bahkan Lighthouse kelihatan hijau. Tapi pas dipakai beneran, transisi masih nyendat, scroll terasa berat, dan tombol kadang telat merespons.

Artikel ini membahas kenapa performa frontend yang terasa smooth tidak cukup dinilai dari skor benchmark. Intinya: user tidak merasakan “angka performa”; user merasakan frame yang konsisten, input yang responsif, dan layout yang tidak loncat-loncat. Buat developer frontend, targetnya bukan sekadar cepat di laporan, tapi stabil saat dipakai di device nyata.

Apa itu frame consistency?

Frame consistency adalah seberapa stabil browser menampilkan perubahan visual dari waktu ke waktu. Kalau aplikasi bergerak 60 frame per detik, tiap frame idealnya punya jatah sekitar 16,7 milidetik. Kalau ada satu frame yang tiba-tiba butuh jauh lebih lama, mata user akan menangkapnya sebagai patah-patah atau jank.

Artikel Every Frame Perfect dari Tonsky menarik karena mengingatkan bahwa UI yang terasa bagus bukan cuma soal fitur visual yang mewah. Kadang justru detail kecil seperti animasi dropdown, perubahan ukuran panel, atau teks yang muncul telat bisa bikin produk terasa “kurang matang”. Diskusi di Hacker News juga ramai karena banyak engineer merasa problem ini sering diabaikan: performa UI bukan cuma urusan game engine, tapi juga web app harian.

Kenapa Lighthouse hijau belum tentu terasa smooth?

Lighthouse dan metrik web performance tetap penting. Gua tidak sedang bilang benchmark itu tidak berguna. Masalahnya, benchmark sering menangkap satu sisi pengalaman: load awal, resource blocking, accessibility dasar, dan beberapa sinyal teknis lain.

Sementara itu, rasa smooth sering muncul setelah halaman sudah hidup:

  • user klik tombol lalu app menjalankan state update besar;
  • dropdown dibuka sambil layout berubah;
  • scroll list panjang memicu render berulang;
  • animasi jalan bareng network request dan parsing data;
  • komponen dipasang ulang padahal yang berubah cuma satu nilai kecil.

Di titik ini, Chrome DevTools Performance lebih relevan dibanding cuma lihat skor. Dokumentasi Chrome DevTools menjelaskan cara merekam runtime performance supaya developer bisa melihat main thread, long task, rendering, scripting, painting, dan interaction. Ini penting karena bottleneck UI sering baru kelihatan saat interaksi direkam, bukan saat halaman diam.

Masalah utamanya sering bukan FPS rata-rata

FPS rata-rata bisa menipu. Misalnya, sebagian besar frame berjalan cepat, tapi setiap beberapa detik ada satu frame berat. Secara angka rata-rata masih terlihat lumayan, tapi secara rasa tetap mengganggu.

Analogi sederhananya: jalanan yang mayoritas mulus tapi tiap 200 meter ada lubang besar. Kalau dihitung rata-rata, perjalanan terlihat oke. Tapi sebagai penumpang, lu tetap merasa tidak nyaman karena hentakan kecil itu muncul berulang.

Di frontend, hentakan itu bisa datang dari layout thrashing, synchronous JavaScript berat, gambar besar yang telat, hydration yang mahal, atau render tree yang terlalu luas. Web.dev punya panduan khusus soal rendering performance dan layout thrashing karena perubahan style/layout yang tidak terkontrol bisa membuat browser menghitung ulang layout lebih sering dari yang perlu.

Checklist cepat buat audit UI yang terasa patah-patah

Kalau lu punya halaman yang “sebenarnya cepat” tapi terasa tidak enak dipakai, gua biasanya mulai dari checklist kecil ini:

1. Rekam interaksi nyata, bukan cuma page load

Buka Chrome DevTools Performance, rekam saat lu melakukan aksi yang terasa berat: klik modal, buka sidebar, scroll tabel, search list, pindah tab, atau submit form. Jangan cuma record halaman pertama kali load.

Tujuannya sederhana: cari frame yang terlalu lama, long task di main thread, dan bagian mana yang makan waktu paling besar. Kalau problem muncul saat klik filter tabel, record klik filter itu. Kalau problem muncul saat scroll, record scroll-nya.

2. Cek apakah layout berubah terlalu sering

Layout thrashing terjadi saat JavaScript berkali-kali membaca dan menulis layout dalam pola yang memaksa browser menghitung ulang posisi elemen. Contohnya: baca ukuran elemen, ubah style, baca ukuran lagi, ubah style lagi, diulang dalam loop.

Kalau halaman punya tabel, grid, sidebar, atau animasi ukuran, ini perlu dicek. Kadang solusi sederhananya bukan rewrite besar, tapi mengelompokkan baca/tulis DOM, menghindari animasi properti layout-heavy, atau pakai transform/opacity untuk efek visual yang lebih ringan.

3. Jangan render ulang satu pohon komponen kalau yang berubah cuma kecil

Di React, Vue, atau Nuxt, problem sering muncul saat state global berubah lalu banyak komponen ikut render ulang. Di layar, user cuma lihat satu badge berubah. Di belakang layar, app bisa saja menghitung ulang banyak komponen.

Ini bukan berarti semua komponen harus di-memo secara agresif. Tapi lu perlu tahu bagian mana yang benar-benar berubah. Pisahkan state lokal, pecah komponen besar, dan hindari dependency reaktif yang terlalu luas.

4. Pakai requestAnimationFrame untuk kerja visual yang harus sinkron dengan repaint

MDN menjelaskan bahwa requestAnimationFrame() meminta browser menjalankan callback sebelum repaint berikutnya. Ini berguna untuk animasi atau update visual yang perlu sinkron dengan siklus render browser.

Namun, ini bukan obat semua masalah. Kalau callback di dalamnya tetap berat, frame tetap bisa telat. Anggap requestAnimationFrame() sebagai cara menaruh kerja visual di waktu yang lebih tepat, bukan izin untuk menumpuk kerja mahal.

5. Test di device yang mendekati user lu

MacBook baru sering menutupi problem UI. Banyak aplikasi terasa aman di mesin developer, tapi berat di laptop kantor, Android menengah, atau browser dengan banyak tab.

Kalau target user lu luas, jangan cuma uji di mesin paling kencang. Minimal pakai CPU throttling di DevTools, tes di browser mobile, dan coba alur utama seperti user beneran: login, buka dashboard, filter data, scroll, lalu submit.

Contoh praktis: dashboard yang terasa berat

Misalnya lu bikin dashboard monitoring. Data cuma 200 item, bukan jutaan. API cepat. Tapi saat user mengetik di search, input terasa delay.

Biasanya gua akan cek beberapa hal:

  • Apakah setiap ketikan langsung mem-filter seluruh data besar di main thread?
  • Apakah tabel render ulang semua row, termasuk row yang tidak terlihat?
  • Apakah highlight text atau badge status dihitung ulang di banyak tempat?
  • Apakah ada watcher/effect yang memicu request atau transform data berulang?
  • Apakah UI melakukan layout ulang karena tinggi row berubah-ubah?

Dari situ, solusi bisa lebih terarah: debounce input, virtualize list, memo hasil filter, pindahkan transform data ke computed yang scope-nya kecil, atau batasi animasi saat data sedang berubah. Ini lebih sehat daripada langsung pasang library baru tanpa tahu sumber masalah.

Takeaway buat developer frontend

  • Skor hijau bukan akhir. Skor bagus membantu, tapi user menilai rasa interaksi.
  • Rekam runtime interaction. Banyak masalah UI baru kelihatan setelah halaman dipakai.
  • Frame yang konsisten lebih penting dari efek visual berlebihan. Animasi sederhana tapi stabil lebih enak daripada animasi keren yang patah.
  • Optimasi harus berbasis bukti. Cari long task, layout thrashing, render ulang, dan paint yang mahal.
  • Test di device realistis. Jangan percaya penuh hasil dari mesin developer yang terlalu kuat.

FAQ singkat

Apakah Lighthouse masih perlu dipakai?

Perlu. Lighthouse tetap bagus untuk audit awal. Tapi jangan berhenti di sana. Untuk rasa smooth, rekam interaksi runtime dengan DevTools Performance.

Apakah semua aplikasi harus mengejar 60 FPS?

Tidak selalu. Aplikasi admin internal dan landing page punya prioritas berbeda. Tapi interaksi utama tetap harus terasa responsif, terutama klik, scroll, input, dan transisi penting.

Apakah animasi harus dihapus biar cepat?

Tidak. Animasi yang tepat bisa membantu user paham perubahan UI. Yang perlu dihindari adalah animasi yang memicu layout berat, durasinya mengganggu, atau jalan di atas state update mahal.

Penutup

Frontend yang bagus bukan cuma yang kelihatan rapi di screenshot. Frontend yang bagus juga terasa stabil saat dipakai.

Menurut gua, ini salah satu skill yang sering membedakan developer yang cuma menyelesaikan tampilan dengan developer yang benar-benar peduli pengalaman user. Lu tidak harus jadi performance engineer ekstrem. Tapi lu perlu punya kebiasaan kecil: record, lihat bukti, perbaiki bottleneck, lalu tes lagi.

Kalau artikel ini relate, simpan buat checklist audit UI berikutnya. Dan kalau lu pernah nemu kasus website skor performanya bagus tapi tetap terasa patah-patah, itu bisa jadi bahan debugging yang menarik banget buat dibahas.

Referensi / Bacaan Lanjut