Mengoptimalkan penundaan input

Cari tahu apa itu penundaan input, dan pelajari teknik untuk menguranginya agar interaktivitas lebih cepat.

Interaksi di web adalah hal yang rumit, dengan segala macam aktivitas yang terjadi di browser untuk menggerakkannya. Namun, kesamaan yang mereka semua miliki adalah bahwa mereka mengakibatkan beberapa penundaan input sebelum callback peristiwa mulai berjalan. Dalam panduan ini, Anda akan mempelajari apa yang dimaksud dengan penundaan input, dan tindakan yang dapat dilakukan untuk meminimalkannya sehingga interaksi situs web berjalan lebih cepat.

Apa yang dimaksud dengan penundaan input?

Penundaan input adalah periode waktu yang dimulai dari saat pengguna pertama kali berinteraksi dengan halaman—seperti mengetuk layar, mengklik dengan mouse, atau menekan tombol—hingga saat callback peristiwa untuk interaksi mulai dijalankan. Setiap interaksi dimulai dengan sejumlah penundaan input.

Visualisasi penundaan input yang disederhanakan. Di sebelah kiri, ada seni garis kursor mouse dengan bintang di belakangnya, menandakan dimulainya interaksi. Di sebelah kanan adalah seni garis roda gigi, yang menandakan saat pengendali peristiwa untuk interaksi mulai berjalan. Spasi di antaranya dicatat sebagai penundaan input dengan tanda kurung kurawal.
Mekanisme di balik penundaan input. Saat diterima oleh sistem operasi, input harus diteruskan ke browser sebelum interaksi dimulai. Proses ini memerlukan waktu tertentu, dan dapat ditingkatkan dengan tugas thread utama yang sudah ada.

Beberapa bagian penundaan input tidak dapat dihindari: sistem operasi selalu memerlukan sejumlah waktu untuk mengenali peristiwa input dan meneruskannya ke browser. Namun, bagian penundaan input tersebut bahkan sering kali tidak terlihat, dan ada hal-hal lain yang terjadi pada halaman itu sendiri yang dapat membuat penundaan input cukup lama sehingga menyebabkan masalah.

Cara mempertimbangkan penundaan input

Secara umum, Anda ingin mempertahankan setiap bagian interaksi sesingkat mungkin sehingga situs Anda memiliki peluang terbaik untuk memenuhi batas "baik" metrik Interaction to Next Paint (INP), terlepas dari perangkat pengguna. Mendeteksi penundaan input hanyalah salah satu bagian dari memenuhi ambang batas itu.

Oleh karena itu, sebaiknya targetkan penundaan input sesingkat mungkin agar dapat memenuhi batas "baik" INP. Namun, Anda harus menyadari bahwa Anda tidak bisa mengharapkan menghilangkan penundaan input sepenuhnya. Selama Anda menghindari pekerjaan thread utama yang berlebihan saat pengguna mencoba berinteraksi dengan halaman Anda, penundaan input Anda harus cukup rendah untuk menghindari masalah.

Cara meminimalkan penundaan input

Seperti yang disebutkan sebelumnya, beberapa penundaan input tidak dapat dihindari, tetapi di sisi lain, beberapa penundaan input dapat dihindari. Berikut ini beberapa hal yang perlu dipertimbangkan jika Anda mengalami kesulitan dengan penundaan input yang lama.

Hindari timer berulang yang memulai tugas thread utama yang berlebihan

Ada dua fungsi timer yang umum digunakan di JavaScript yang dapat berkontribusi pada penundaan input: setTimeout dan setInterval. Perbedaan di antara keduanya adalah setTimeout menjadwalkan callback untuk dijalankan setelah waktu yang ditentukan. Di sisi lain, setInterval menjadwalkan callback untuk dijalankan setiap n milidetik terus-menerus, atau sampai timer dihentikan dengan clearInterval.

setTimeout tidak bermasalah dengan sendirinya—bahkan, dapat berguna untuk menghindari tugas yang berjalan lama. Namun, hal ini bergantung pada kapan waktu tunggu terjadi, dan apakah pengguna mencoba berinteraksi dengan halaman saat callback waktu tunggu berjalan.

Selain itu, setTimeout dapat dijalankan dalam loop atau secara rekursif, yang berfungsi lebih seperti setInterval, meskipun sebaiknya tidak menjadwalkan iterasi berikutnya hingga iterasi sebelumnya selesai. Meskipun ini berarti loop akan menghasilkan thread utama setiap kali setTimeout dipanggil, Anda harus berhati-hati untuk memastikan callback-nya tidak melakukan pekerjaan berlebihan.

setInterval menjalankan callback pada suatu interval, dan oleh karena itu, jauh lebih mungkin menghalangi interaksi. Hal ini karena—tidak seperti satu panggilan setTimeout, yang merupakan callback satu kali yang mungkin menghalangi interaksi pengguna—sifat berulang setInterval membuatnya akan menghalangi interaksi, sehingga meningkatkan penundaan input interaksi.

Screenshot profiler performa di Chrome DevTools yang menunjukkan penundaan input. Tugas yang diaktifkan oleh fungsi timer terjadi tepat sebelum pengguna memulai interaksi klik. Akan tetapi, timer akan menambah penundaan input, menyebabkan callback peristiwa interaksi berjalan lebih lambat dari yang seharusnya.
Timer yang didaftarkan oleh panggilan setInterval sebelumnya menyebabkan penundaan input seperti yang ditunjukkan di panel performa Chrome DevTools. Penundaan input yang ditambahkan menyebabkan callback peristiwa untuk interaksi berjalan lebih lambat dari yang seharusnya.

Jika timer terjadi dalam kode pihak pertama, Anda dapat mengontrolnya. Evaluasi apakah Anda memerlukannya, atau lakukan yang terbaik untuk mengurangi beban kerja Anda sebanyak mungkin. Namun, timer dalam skrip pihak ketiga berbeda cerita. Sering kali Anda tidak memiliki kontrol atas apa yang dilakukan skrip pihak ketiga, dan memperbaiki masalah performa dalam kode pihak ketiga sering kali melibatkan kerja sama dengan pemangku kepentingan untuk menentukan apakah skrip pihak ketiga tertentu diperlukan, dan jika demikian, hubungi vendor skrip pihak ketiga untuk menentukan apa yang dapat dilakukan untuk memperbaiki masalah performa yang mungkin disebabkan oleh mereka di situs Anda.

Hindari tugas yang berjalan lama

Salah satu cara untuk mengurangi penundaan {i>input<i} yang lama adalah dengan menghindari tugas yang berjalan lama. Jika Anda memiliki pekerjaan thread utama berlebihan yang memblokir thread utama selama interaksi, hal tersebut akan menambah penundaan input untuk tugas yang panjang sebelum tugas yang panjang memiliki kesempatan untuk diselesaikan.

Visualisasi seberapa lama tugas memperpanjang penundaan input. Di bagian atas, interaksi terjadi sesaat setelah satu tugas panjang berjalan, menyebabkan penundaan input yang signifikan yang menyebabkan callback peristiwa berjalan lebih lambat dari yang seharusnya. Di bagian bawah, interaksi terjadi pada waktu yang hampir bersamaan, namun tugas yang panjang dipecah menjadi beberapa tugas yang lebih kecil dengan menghasilkan, sehingga callback peristiwa interaksi dapat berjalan lebih cepat.
Visualisasi hal yang terjadi pada interaksi jika tugas terlalu panjang dan browser tidak dapat merespons interaksi dengan cukup cepat, dibandingkan saat tugas yang lebih panjang dipecah menjadi tugas yang lebih kecil.

Selain meminimalkan jumlah pekerjaan yang Anda lakukan dalam suatu tugas—dan Anda harus selalu berusaha melakukan pekerjaan sesedikit mungkin di thread utama—Anda dapat meningkatkan responsivitas terhadap input pengguna dengan memecah tugas-tugas yang panjang.

Memperhatikan interaksi tumpang-tindih

Bagian yang sangat menantang dalam mengoptimalkan INP adalah jika Anda memiliki interaksi yang tumpang tindih. Interaksi tumpang-tindih berarti bahwa setelah Anda berinteraksi dengan satu elemen, Anda melakukan interaksi lain dengan halaman sebelum interaksi awal memiliki kesempatan untuk merender bingkai berikutnya.

Penggambaran kapan tugas dapat tumpang tindih untuk menghasilkan penundaan input yang lama. Dalam penggambaran ini, interaksi klik tumpang tindih dengan interaksi keydown untuk meningkatkan penundaan input untuk interaksi keydown.
Visualisasi dua interaksi serentak di profiler performa di Chrome DevTools. Pekerjaan rendering dalam interaksi klik awal menyebabkan penundaan input untuk interaksi keyboard berikutnya.

Sumber tumpang tindih interaksi mungkin semudah pengguna membuat banyak interaksi dalam waktu singkat. Hal ini dapat terjadi saat pengguna mengetik di kolom formulir, tempat banyak interaksi keyboard dapat terjadi dalam jangka waktu yang sangat singkat. Jika pekerjaan pada peristiwa tombol sangat mahal—seperti dalam kasus umum kolom pelengkapan otomatis tempat permintaan jaringan dibuat ke backend—Anda memiliki beberapa opsi:

  • Pertimbangkan untuk mengulangi input guna membatasi frekuensi callback peristiwa dijalankan dalam jangka waktu tertentu.
  • Gunakan AbortController untuk membatalkan permintaan fetch keluar sehingga thread utama tidak mengalami kepadatan saat menangani callback fetch. Catatan: Properti signal instance AbortController juga dapat digunakan untuk membatalkan peristiwa.

Sumber lain dari peningkatan penundaan {i>input<i} karena interaksi yang tumpang tindih dapat berupa animasi yang mahal. Secara khusus, animasi di JavaScript dapat mengaktifkan banyak panggilan requestAnimationFrame, yang mungkin menghalangi interaksi pengguna. Untuk mengatasi hal ini, gunakan animasi CSS jika memungkinkan untuk menghindari antrean frame animasi yang berpotensi mahal—tetapi jika Anda melakukannya, pastikan Anda menghindari animasi yang tidak digabungkan sehingga animasi berjalan terutama di thread GPU dan compositor, dan bukan di thread utama.

Kesimpulan

Meskipun penundaan input mungkin tidak mewakili sebagian besar waktu interaksi Anda berjalan, penting untuk dipahami bahwa setiap bagian interaksi membutuhkan sejumlah waktu yang dapat Anda kurangi. Jika Anda mengamati penundaan input yang lama, Anda memiliki peluang untuk menguranginya. Menghindari callback timer yang berulang, membagi tugas yang panjang, dan mengetahui potensi interaksi tumpang-tindih dapat membantu Anda mengurangi penundaan input, sehingga meningkatkan interaktivitas bagi pengguna situs Anda.

Banner besar dari Unsplash, oleh Erik Mclean.