Mengoptimalkan Penundaan Input Pertama

Cara merespons interaksi pengguna dengan lebih cepat.

Saya mengklik, tetapi tidak ada yang terjadi. Mengapa saya tidak dapat berinteraksi dengan halaman ini? 😢

First Contentful Paint (FCP) dan Largest Contentful Paint (LCP) adalah metrik yang mengukur waktu yang dibutuhkan untuk membuat konten merender (melukis) secara visual pada halaman. Meskipun penting, waktu cat tidak menangkap beban responsivitas: atau seberapa cepat halaman merespons interaksi pengguna.

Penundaan Input Pertama (FID) adalah metrik Data Web Inti yang merekam kesan pertama dari interaktivitas dan responsivitas situs. Metrik ini mengukur waktu dari saat pengguna berinteraksi dengan halaman pertama kali hingga browser benar-benar dapat interaksi. FID adalah metrik kolom dan tidak dapat disimulasikan di lingkungan lab. Interaksi pengguna yang nyata diperlukan untuk mengukur penundaan respons.

Nilai fid yang baik adalah 2,5 detik, nilai yang buruk lebih besar dari 4,0 detik dan apa pun di antaranya perlu perbaikan

Untuk membantu memprediksi FID di lab, kita rekomendasikan Total Waktu Pemblokiran (TBT). Mereka mengukur hal yang berbeda, tetapi peningkatan TBT biasanya disesuaikan dengan peningkatan FID.

Penyebab utama FID yang buruk adalah eksekusi JavaScript yang berat. Mengoptimalkan cara JavaScript mengurai, dikompilasi, dan dieksekusi di laman web Anda akan mengurangi FID secara langsung.

Eksekusi JavaScript berat

Browser tidak dapat merespons sebagian besar input pengguna saat sedang mengeksekusi JavaScript di thread utama. Dengan kata lain, browser tidak dapat merespons interaksi pengguna saat thread utama sibuk. Untuk memperbaikinya:

Pisahkan Tugas yang Lama

Jika Anda sudah mencoba mengurangi jumlah JavaScript yang dimuat di satu halaman, hal itu dapat berguna untuk memecah kode yang berjalan lama menjadi tugas asinkron yang lebih kecil.

Tugas yang Lama adalah periode eksekusi JavaScript yang memungkinkan pengguna menemukan UI Anda tidak responsif. Setiap potongan kode yang memblokir thread utama selama 50 md atau lebih dapat yang ditandai sebagai Tugas Panjang. Tugas yang Berdurasi Panjang adalah tanda potensi penggelembungan JavaScript (memuat dan mengeksekusi lebih dari yang dibutuhkan pengguna saat ini). Memisahkan tugas yang panjang dapat mengurangi penundaan input di situs Anda.

Tugas Berdurasi Panjang di Chrome DevTools
Chrome DevTools memvisualisasikan Tugas yang Berjalan Lama di Panel Performa

FID akan meningkat secara signifikan saat Anda mengadopsi praktik terbaik seperti memecah kode dan Tugas Berdurasi Panjang. Meskipun TBT bukan metrik lapangan, ini berguna untuk memeriksa kemajuan menuju meningkatkan Time To Interactive (TTI) dan FID.

Optimalkan halaman Anda untuk kesiapan interaksi

Ada sejumlah penyebab umum skor FID dan TBT yang buruk di aplikasi web yang sangat bergantung pada JavaScript:

Eksekusi skrip pihak pertama dapat menunda kesiapan interaksi

  • Penggembungan ukuran JavaScript, waktu eksekusi yang berat, dan pemotongan yang tidak efisien dapat memperlambat seberapa cepat dapat merespons input pengguna serta memengaruhi FID, TBT, dan TTI. Pemuatan kode secara progresif dan dapat membantu menyebarkan latihan ini dan meningkatkan kesiapan interaksi.
  • Aplikasi yang dirender sisi server mungkin terlihat seperti mendapatkan piksel yang dilukis di layar dengan cepat, tetapi waspadai interaksi pengguna yang diblokir oleh eksekusi skrip yang besar (mis. hidrasi ulang untuk menghubungkan pemroses peristiwa). Proses ini memerlukan waktu beberapa ratus milidetik, terkadang bahkan detik, jika pemisahan kode berbasis rute digunakan. Pertimbangkan untuk menggeser lebih banyak logika sisi server atau menghasilkan lebih banyak konten secara statis selama waktu {i>build<i}.

Berikut adalah skor TBT sebelum dan sesudah pengoptimalan pemuatan skrip pihak pertama untuk aplikasi. Dengan memindahkan pemuatan skrip yang mahal (dan eksekusi) untuk komponen yang tidak penting dari kritis, pengguna dapat berinteraksi dengan laman lebih cepat.

Peningkatan skor TBT di Lighthouse setelah mengoptimalkan skrip pihak pertama.

Pengambilan data dapat memengaruhi banyak aspek kesiapan interaksi

  • Menunggu waterfall pengambilan berjenjang (misalnya JavaScript dan pengambilan data untuk komponen) dapat dampak latensi interaksi. Usahakan untuk meminimalkan ketergantungan pada pengambilan data secara beruntun.
  • Datastore inline yang besar dapat mendorong waktu penguraian HTML dan memengaruhi paint dan interaksi metrik. Bertujuan untuk meminimalkan jumlah data yang perlu diproses kembali di sisi klien.

Eksekusi skrip pihak ketiga juga dapat menunda latensi interaksi

  • Banyak situs menyertakan tag dan analisis pihak ketiga yang dapat membuat jaringan tetap aktif dan membuat thread utama tidak responsif secara berkala, sehingga memengaruhi latensi interaksi. Eksplorasi pemuatan on demand kode pihak ketiga (misalnya, mungkin tidak memuat iklan paruh bawah tersebut hingga di-scroll mendekati area pandang).
  • Dalam beberapa kasus, skrip pihak ketiga dapat mengungguli skrip pihak pertama dalam hal prioritas dan di thread utama, juga menunda seberapa cepat halaman siap untuk berinteraksi. Upaya untuk memprioritaskan pemuatan apa yang Anda yakini menawarkan nilai terbesar kepada pengguna terlebih dahulu.

Menggunakan pekerja web

Thread utama yang diblokir adalah salah satu penyebab utama penundaan input. Web worker dapat menjalankan JavaScript di thread latar belakang. Memindahkan operasi non-UI ke thread pekerja terpisah dapat mengurangi waktu pemblokiran thread dan akibatnya meningkatkan FID.

Pertimbangkan untuk menggunakan library berikut agar lebih mudah menggunakan pekerja web di situs Anda:

  • Comlink: Library helper yang memisahkan postMessage serta mempermudah penggunaannya
  • Workway: Pengekspor pekerja web tujuan umum
  • Workerize: Memindahkan modul ke web worker

Mengurangi waktu eksekusi JavaScript

Membatasi jumlah JavaScript di halaman akan mengurangi jumlah waktu yang diperlukan browser gunakan untuk mengeksekusi kode JavaScript. Hal ini mempercepat seberapa cepat browser dapat mulai merespons setiap interaksi pengguna.

Untuk mengurangi jumlah JavaScript yang dieksekusi di halaman Anda:

  • Tunda JavaScript yang tidak digunakan
  • Minimalkan polyfill yang tidak digunakan

Tunda JavaScript yang tidak digunakan

Secara default, semua JavaScript memblokir render. Saat browser menemukan tag skrip yang tertaut ke file JavaScript eksternal, file tersebut harus menghentikan sementara apa yang dilakukannya dan mengunduh, mengurai, mengompilasi, dan mengeksekusi JavaScript tersebut. Oleh karena itu, Anda sebaiknya hanya memuat kode yang diperlukan untuk halaman atau merespons input pengguna.

Tab Cakupan di Chrome DevTools dapat memberi tahu Anda seberapa banyak JavaScript yang tidak digunakan di halaman web Anda.

Tab Cakupan.

Untuk mengurangi JavaScript yang tidak digunakan:

  • Bagi kode paket Anda menjadi beberapa bagian
  • Tunda JavaScript yang tidak penting, termasuk skrip pihak ketiga, menggunakan async atau defer

Pemisahan kode adalah konsep pemisahan satu paket JavaScript besar menjadi potongan-potongan yang lebih kecil yang dapat dimuat secara bersyarat (disebut juga pemuatan lambat). Sebagian besar browser yang lebih baru mendukung sintaksis impor dinamis, yang memungkinkan pengambilan modul sesuai permintaan:

import('module.js').then((module) => {
  // Do something with the module.
});

Mengimpor JavaScript secara dinamis pada interaksi pengguna tertentu (seperti mengubah rute atau menampilkan modal) akan memastikan bahwa kode yang tidak digunakan untuk pemuatan halaman awal hanya diambil saat diperlukan.

Selain dukungan browser umum, sintaksis impor dinamis dapat digunakan dalam banyak versi yang berbeda.

  • Jika Anda menggunakan webpack, Gabungan, atau Parcel sebagai pemaket modul, manfaatkan mendukung impor dinamis mereka.
  • Framework sisi klien, seperti Bereaksi, Angular, dan Vue menyediakan abstraksi untuk mempermudah pemuatan lambat pada level komponen.

Selain pemisahan kode, selalu gunakan metode asinkron atau tunda untuk skrip yang tidak diperlukan untuk {i>critical-path<i} atau konten {i>above-the-fold<i}.

<script defer src="…"></script>
<script async src="…"></script>

Kecuali ada alasan khusus untuk tidak melakukannya, semua skrip pihak ketiga harus dimuat dengan defer atau async secara default.

Minimalkan polyfill yang tidak digunakan

Jika Anda menulis kode menggunakan sintaksis JavaScript modern dan mereferensikan API browser modern, Anda akan perlu melakukan transpilasi dan menyertakan polyfill agar dapat berfungsi di browser yang lebih lama.

Salah satu masalah performa utama termasuk polyfill dan kode yang ditranspilasi di situs Anda adalah {i>browser<i} yang lebih baru tidak perlu mengunduhnya jika mereka tidak membutuhkannya. Untuk mengurangi JavaScript ukuran aplikasi, minimalkan polyfill yang tidak digunakan, dan batasi penggunaannya lingkungan di mana mereka membutuhkannya.

Untuk mengoptimalkan penggunaan polyfill di situs Anda:

  • Jika Anda menggunakan Babel sebagai transpiler, gunakan @babel/preset-env agar hanya menyertakan polyfill yang diperlukan untuk browser yang ingin Anda targetkan. Untuk Babel 7.9, aktifkan Opsi bugfixes untuk mengurangi pada setiap polyfill yang tidak diperlukan
  • Gunakan pola modul/nomodule untuk mengirimkan dua paket terpisah (juga @babel/preset-env) mendukung ini melalui target.esmodules)

    <script type="module" src="modern.js"></script>
    <script nomodule src="legacy.js" defer></script>
    

    Banyak fitur ECMAScript baru yang dikompilasi dengan Babel sudah didukung di lingkungan yang mendukung modul JavaScript. Jadi dengan melakukannya, Anda menyederhanakan proses untuk memastikan bahwa hanya kode transpilasi yang digunakan untuk {i>browser<i} yang benar-benar membutuhkannya.

Developer tools

Tersedia sejumlah alat untuk mengukur dan men-debug FID:

Terima kasih kepada Philip Walton, Kayce Basques, Ilya Grigorik, dan Annie Sullivan atas ulasan mereka.