Pelajari cara mengoptimalkan Interaction to Next Paint situs Anda.
Interaction to Next Paint (INP) adalah metrik Core Web Vitals stabil yang menilai responsivitas keseluruhan halaman terhadap interaksi pengguna dengan mengamati latensi semua interaksi yang memenuhi syarat yang terjadi selama masa aktif kunjungan pengguna ke halaman. Nilai INP akhir adalah interaksi terpanjang yang diamati (terkadang mengabaikan pencilan).
Untuk memberikan pengalaman pengguna yang baik, situs harus berusaha memiliki Interaction to Next Paint 200 milidetik atau kurang. Untuk memastikan Anda mencapai target ini bagi sebagian besar pengguna, nilai minimum yang baik untuk diukur adalah persentil ke-75 pemuatan halaman, yang disegmentasikan di seluruh perangkat seluler dan desktop.
Bergantung pada situsnya, mungkin ada sedikit atau tidak ada interaksi—seperti halaman yang sebagian besar berisi teks dan gambar dengan sedikit atau tidak ada elemen interaktif. Atau, dalam kasus situs seperti editor teks atau game, mungkin ada ratusan—bahkan ribuan—interaksi. Dalam kedua kasus tersebut, jika INP tinggi, pengalaman pengguna akan berisiko.
Perlu waktu dan upaya untuk meningkatkan INP, tetapi hasilnya adalah pengalaman pengguna yang lebih baik. Dalam panduan ini, jalur untuk meningkatkan INP akan dipelajari.
Mencari tahu penyebab INP yang buruk
Sebelum dapat memperbaiki interaksi yang lambat, Anda memerlukan data untuk mengetahui apakah INP situs Anda buruk atau perlu ditingkatkan. Setelah memiliki informasi tersebut, Anda dapat melanjutkan ke lab untuk mulai mendiagnosis interaksi yang lambat, dan mencari solusinya.
Menemukan interaksi lambat di lapangan
Idealnya, perjalanan Anda dalam mengoptimalkan INP akan dimulai dengan data kolom. Jika optimal, data kolom dari penyedia Real User Monitoring (RUM) tidak hanya akan memberi Anda nilai INP halaman, tetapi juga data kontekstual yang menyoroti interaksi spesifik yang bertanggung jawab atas nilai INP itu sendiri, baik interaksi terjadi selama atau setelah pemuatan halaman, jenis interaksi (klik, penekanan tombol, atau ketukan), dan informasi berharga lainnya.
Jika Anda tidak mengandalkan penyedia RUM untuk mendapatkan data kolom, panduan data kolom INP menyarankan untuk menggunakan Laporan Pengalaman Pengguna Chrome (CrUX) melalui PageSpeed Insights untuk membantu mengisi kekurangan data. CrUX adalah set data resmi program Core Web Vitals dan memberikan ringkasan metrik tingkat tinggi untuk jutaan situs, termasuk INP. Namun, CrUX sering kali tidak memberikan data kontekstual yang akan Anda dapatkan dari penyedia RUM untuk membantu Anda menganalisis masalah. Oleh karena itu, sebaiknya situs menggunakan penyedia RUM jika memungkinkan, atau menerapkan solusi RUM mereka sendiri untuk melengkapi yang tersedia di CrUX.
Mendiagnosis interaksi yang lambat di lab
Idealnya, Anda ingin mulai melakukan pengujian di lab setelah memiliki data lapangan yang menunjukkan bahwa Anda memiliki interaksi yang lambat. Jika tidak ada data lapangan, ada beberapa strategi untuk mengidentifikasi interaksi lambat di lab. Strategi tersebut mencakup mengikuti alur penggunaan umum dan menguji interaksi di sepanjang proses, serta berinteraksi dengan halaman selama pemuatan—saat thread utama sering kali paling sibuk—untuk menampilkan interaksi lambat selama bagian penting dari pengalaman pengguna tersebut.
Mengoptimalkan interaksi
Setelah Anda mengidentifikasi interaksi yang lambat dan dapat mereproduksinya secara manual di lab, langkah berikutnya adalah mengoptimalkannya. Interaksi dapat dibagi menjadi tiga fase:
- Penundaan input, yang dimulai saat pengguna memulai interaksi dengan halaman, dan berakhir saat callback peristiwa untuk interaksi mulai berjalan.
- Durasi pemrosesan, yang terdiri dari waktu yang diperlukan untuk menjalankan callback peristiwa hingga selesai.
- Penundaan presentasi, yaitu waktu yang diperlukan browser untuk menampilkan frame berikutnya yang berisi hasil visual interaksi.
Jumlah dari ketiga fase ini adalah total latensi interaksi. Setiap fase interaksi berkontribusi pada jumlah waktu tertentu terhadap total latensi interaksi. Oleh karena itu, penting untuk mengetahui cara mengoptimalkan setiap bagian interaksi agar berjalan dalam waktu sesedikit mungkin.
Mengidentifikasi dan mengurangi penundaan input
Saat pengguna berinteraksi dengan halaman, bagian pertama dari interaksi tersebut adalah penundaan input. Bergantung pada aktivitas lain di halaman, penundaan input dapat berlangsung cukup lama. Hal ini dapat disebabkan oleh aktivitas yang terjadi di thread utama (mungkin karena pemuatan, penguraian, dan kompilasi skrip), penanganan pengambilan, fungsi timer, atau bahkan dari interaksi lain yang terjadi secara berurutan dan tumpang-tindih satu sama lain.
Apa pun sumber penundaan input interaksi, Anda harus mengurangi penundaan input seminimal mungkin sehingga interaksi dapat mulai menjalankan callback peristiwa sesegera mungkin.
Hubungan antara evaluasi skrip dan tugas yang lama selama startup
Aspek penting dari interaktivitas dalam siklus proses halaman adalah selama startup. Saat dimuat, halaman pada awalnya akan dirender. Namun, penting untuk diingat bahwa hanya karena halaman telah dirender, tidak berarti halaman tersebut selesai dimuat. Bergantung pada jumlah resource yang diperlukan halaman agar berfungsi secara penuh, pengguna mungkin dapat mencoba berinteraksi dengan halaman saat masih dimuat.
Salah satu hal yang dapat memperpanjang penundaan input interaksi saat halaman dimuat adalah evaluasi skrip. Setelah file JavaScript diambil dari jaringan, browser masih memiliki pekerjaan yang harus dilakukan sebelum JavaScript tersebut dapat berjalan; pekerjaan tersebut mencakup mengurai skrip untuk memastikan sintaksisnya valid, mengompilasi menjadi bytecode, lalu akhirnya mengeksekusinya.
Bergantung pada ukuran skrip, pekerjaan ini dapat menyebabkan tugas yang lama di thread utama, yang akan menunda browser merespons interaksi pengguna lainnya. Agar halaman tetap responsif terhadap input pengguna selama pemuatan halaman, penting untuk memahami tindakan yang dapat Anda lakukan untuk mengurangi kemungkinan tugas yang lama selama pemuatan halaman sehingga halaman tetap cepat.
Mengoptimalkan callback peristiwa
Penundaan input hanyalah bagian pertama dari hal yang diukur INP. Anda juga harus memastikan bahwa callback peristiwa yang berjalan sebagai respons terhadap interaksi pengguna dapat diselesaikan secepat mungkin.
Sering kali menyerahkan ke thread utama
Saran umum terbaik dalam mengoptimalkan callback peristiwa adalah melakukan pekerjaan sesedikit mungkin di dalamnya. Namun, logika interaksi Anda mungkin kompleks, dan Anda mungkin hanya dapat mengurangi pekerjaan yang dilakukannya secara marginal.
Jika Anda menemukan hal ini terjadi pada situs Anda, hal berikutnya yang dapat Anda coba adalah membagi pekerjaan dalam callback peristiwa menjadi tugas terpisah. Hal ini mencegah pekerjaan kolektif menjadi tugas panjang yang memblokir thread utama, yang memungkinkan interaksi lain yang akan menunggu thread utama untuk berjalan lebih cepat.
setTimeout
adalah salah satu cara untuk membagi tugas, karena callback yang diteruskan ke callback tersebut berjalan dalam tugas baru. Anda dapat menggunakan setTimeout
sendiri atau memisahkan penggunaannya ke dalam fungsi terpisah untuk hasil yang lebih ergonomis.
Memberikan hasil secara tidak pandang bulu lebih baik daripada tidak memberikan hasil sama sekali—tetapi, ada cara yang lebih terperinci untuk memberikan hasil ke thread utama, dan cara ini hanya melibatkan pemberian hasil segera setelah callback peristiwa yang memperbarui antarmuka pengguna sehingga logika rendering dapat berjalan lebih cepat.
Menghasilkan untuk memungkinkan pekerjaan rendering terjadi lebih cepat
Teknik menghasilkan yang lebih canggih melibatkan penataan kode dalam callback peristiwa untuk membatasi apa yang dijalankan hanya pada logika yang diperlukan guna menerapkan update visual untuk frame berikutnya. Semua hal lainnya dapat ditangguhkan ke tugas berikutnya. Hal ini tidak hanya membuat callback tetap ringan dan gesit, tetapi juga meningkatkan waktu rendering untuk interaksi dengan tidak mengizinkan update visual memblokir kode callback peristiwa.
Misalnya, bayangkan editor teks kaya yang memformat teks saat Anda mengetik, tetapi juga memperbarui aspek UI lainnya sebagai respons terhadap apa yang telah Anda tulis (seperti jumlah kata, menandai kesalahan ejaan, dan masukan visual penting lainnya). Selain itu, aplikasi mungkin juga perlu menyimpan apa yang telah Anda tulis sehingga jika Anda keluar dan kembali, Anda tidak akan kehilangan pekerjaan apa pun.
Dalam contoh ini, empat hal berikut harus terjadi sebagai respons terhadap karakter yang diketik oleh pengguna. Namun, hanya item pertama yang perlu dilakukan sebelum frame berikutnya ditampilkan.
- Perbarui kotak teks dengan apa yang diketik pengguna dan terapkan format yang diperlukan.
- Perbarui bagian UI yang menampilkan jumlah kata saat ini.
- Jalankan logika untuk memeriksa kesalahan ejaan.
- Menyimpan perubahan terbaru (secara lokal atau ke database jarak jauh).
Kode untuk melakukannya mungkin terlihat seperti berikut:
textBox.addEventListener('input', (inputEvent) => {
// Update the UI immediately, so the changes the user made
// are visible as soon as the next frame is presented.
updateTextBox(inputEvent);
// Use `setTimeout` to defer all other work until at least the next
// frame by queuing a task in a `requestAnimationFrame()` callback.
requestAnimationFrame(() => {
setTimeout(() => {
const text = textBox.textContent;
updateWordCount(text);
checkSpelling(text);
saveChanges(text);
}, 0);
});
});
Visualisasi berikut menunjukkan bagaimana menunda update non-penting hingga setelah frame berikutnya dapat mengurangi durasi pemrosesan dan dengan demikian latensi interaksi secara keseluruhan.
Meskipun penggunaan setTimeout()
di dalam panggilan requestAnimationFrame()
dalam contoh kode sebelumnya memang agak esoterik, ini merupakan metode efektif yang berfungsi di semua browser untuk memastikan bahwa kode yang tidak penting tidak memblokir frame berikutnya.
Menghindari thrashing tata letak
Layout thrashing—terkadang disebut tata letak sinkron paksa—adalah masalah performa rendering saat tata letak terjadi secara sinkron. Hal ini terjadi saat Anda memperbarui gaya di JavaScript, lalu membacanya dalam tugas yang sama—dan ada banyak properti di JavaScript yang dapat menyebabkan thrashing tata letak.
Layout thrashing merupakan bottleneck performa karena dengan mengupdate gaya lalu segera meminta nilai gaya tersebut di JavaScript, browser akan dipaksa untuk melakukan pekerjaan tata letak sinkron. Jika tidak, browser bisa menunggu untuk berjalan secara asinkron nanti setelah callback peristiwa selesai berjalan.
Meminimalkan penundaan presentasi
Penundaan presentasi tanda interaksi berlangsung dari saat callback peristiwa interaksi selesai berjalan, hingga saat browser dapat menggambar frame berikutnya yang menampilkan perubahan visual yang dihasilkan.
Meminimalkan ukuran DOM
Jika DOM halaman berukuran kecil, proses rendering biasanya selesai dengan cepat. Namun, jika DOM menjadi sangat besar, pekerjaan rendering cenderung diskalakan dengan bertambahnya ukuran DOM. Hubungan antara tugas rendering dan ukuran DOM bukan yang linear, namun DOM besar membutuhkan lebih banyak upaya untuk dirender daripada DOM kecil. DOM yang besar menimbulkan masalah dalam dua kasus:
- Selama rendering halaman awal, DOM yang besar memerlukan banyak pekerjaan untuk merender status awal halaman.
- Sebagai respons terhadap interaksi pengguna, DOM yang besar dapat menyebabkan update rendering menjadi sangat tidak efisien, sehingga meningkatkan waktu yang dibutuhkan browser untuk menampilkan frame berikutnya.
Perlu diingat bahwa ada kasus saat DOM besar tidak dapat dikurangi secara signifikan. Meskipun ada pendekatan yang dapat Anda lakukan untuk mengurangi ukuran DOM, seperti meratakan DOM atau menambahkan ke DOM selama interaksi pengguna agar ukuran DOM awal tetap kecil, teknik tersebut mungkin tidak akan banyak membantu.
Menggunakan content-visibility
untuk merender elemen di luar layar secara lambat
Salah satu cara untuk membatasi jumlah pekerjaan rendering selama pemuatan halaman dan pekerjaan rendering sebagai respons terhadap interaksi pengguna adalah dengan mengandalkan properti content-visibility
CSS, yang secara efektif berarti merender elemen secara lambat saat mendekati area tampilan. Meskipun content-visibility
dapat memerlukan beberapa latihan untuk digunakan secara efektif, sebaiknya selidiki apakah hasilnya adalah waktu rendering yang lebih rendah yang dapat meningkatkan INP halaman Anda.
Perhatikan biaya performa saat merender HTML menggunakan JavaScript
Jika ada HTML, ada penguraian HTML, dan setelah browser selesai menguraikan HTML menjadi DOM, browser harus menerapkan gaya ke DOM, melakukan penghitungan tata letak, dan kemudian merender tata letak tersebut. Ini adalah biaya yang tidak dapat dihindari, tetapi cara Anda melakukan rendering HTML sangatlah penting.
Saat server mengirim HTML, HTML akan masuk ke browser sebagai streaming. Streaming berarti bahwa respons HTML dari server tiba dalam potongan. Browser mengoptimalkan cara menangani streaming dengan mengurai potongan streaming secara bertahap saat tiba, dan merendernya sedikit demi sedikit. Ini adalah pengoptimalan performa karena browser secara implisit menghasilkan secara berkala dan otomatis selama pemuatan halaman, dan Anda mendapatkannya secara gratis.
Meskipun kunjungan pertama ke situs mana pun akan selalu melibatkan sejumlah HTML, pendekatan umum dimulai dengan sedikit HTML awal, lalu JavaScript digunakan untuk mengisi area konten. Pembaruan berikutnya pada area konten tersebut juga terjadi sebagai hasil dari interaksi pengguna. Hal ini biasanya disebut model aplikasi web satu halaman (SPA). Salah satu kelemahan pola ini adalah, dengan merender HTML dengan JavaScript di klien, Anda tidak hanya mendapatkan biaya pemrosesan JavaScript untuk membuat HTML tersebut, tetapi juga browser tidak akan menghasilkan hingga selesai mengurai HTML tersebut, dan merendernya.
Namun, penting untuk diingat bahwa bahkan situs yang bukan SPA mungkin akan melibatkan sejumlah rendering HTML melalui JavaScript sebagai hasil interaksi. Hal ini umumnya tidak masalah, selama Anda tidak merender HTML dalam jumlah besar di klien, yang dapat menunda presentasi frame berikutnya. Namun, penting untuk memahami implikasi performa dari pendekatan ini untuk merender HTML di browser, dan bagaimana hal ini dapat memengaruhi responsivitas situs Anda terhadap input pengguna jika Anda merender banyak HTML melalui JavaScript.
Kesimpulan
Meningkatkan INP situs Anda adalah proses berulang. Saat Anda memperbaiki interaksi lambat di lapangan, kemungkinan besar—terutama jika situs Anda menyediakan banyak interaktivitas—Anda akan mulai menemukan interaksi lambat lainnya, dan Anda juga harus mengoptimalkannya.
Kunci untuk meningkatkan INP adalah persistensi. Pada waktunya, Anda bisa menyesuaikan respons halaman sehingga pengguna puas dengan pengalaman yang Anda berikan. Kemungkinan besar, saat mengembangkan fitur baru untuk pengguna, Anda mungkin perlu melalui proses yang sama dalam mengoptimalkan interaksi khusus untuk mereka. Hal ini akan memerlukan waktu dan tenaga, tetapi waktu dan tenaga tersebut akan terbayar.
Gambar hero dari Unsplash, oleh David Pisnoy dan diubah sesuai dengan lisensi Unsplash.