Menghindari cat yang tidak perlu

Pengantar

Menggambar elemen untuk sebuah situs atau aplikasi bisa jadi sangat mahal, dan bisa berdampak negatif pada performa runtime kita. Dalam artikel ini, kita akan melihat sekilas hal yang dapat memicu proses menggambar di browser, dan cara mencegah proses menggambar yang tidak perlu.

Lukisan: Tur super cepat

Salah satu tugas utama yang harus dilakukan browser adalah mengonversi DOM dan CSS menjadi piksel di layar, dan browser melakukannya melalui proses yang cukup kompleks. Proses ini dimulai dengan membaca markup dan dari sini, browser akan membuat hierarki DOM. Hal yang sama dilakukan dengan CSS dan dari situ CSSOM akan dibuat. DOM dan CSSOM kemudian digabungkan dan, pada akhirnya, kita akan sampai pada struktur tempat kita dapat mulai menggambar beberapa piksel.

Proses menggambar itu sendiri menarik. Di Chrome, pohon gabungan DOM dan CSS dirasterisasi oleh beberapa software yang disebut Skia. Jika Anda pernah menggunakan elemen canvas, API Skia akan terlihat sangat familiar bagi Anda; ada banyak fungsi bergaya moveTo dan lineTo serta banyak fungsi yang lebih canggih. Pada dasarnya, semua elemen yang perlu digambar distilasi menjadi kumpulan panggilan Skia yang dapat dieksekusi, dan output-nya adalah sekumpulan bitmap. Bitmap ini diupload ke GPU, dan GPU membantu dengan mengomposisikannya bersama-sama untuk memberi kita gambar akhir di layar.

Dom ke piksel

Hal yang perlu diambil adalah bahwa beban kerja Skia dipengaruhi secara langsung oleh gaya yang Anda terapkan pada elemen. Jika Anda menggunakan gaya yang berat secara algoritma, Skia akan memiliki lebih banyak pekerjaan yang harus dilakukan. Colt McAnlis telah menulis artikel tentang pengaruh CSS terhadap berat rendering halaman, jadi Anda harus membacanya untuk mendapatkan insight lebih lanjut.

Dengan semua hal yang telah disebutkan, pekerjaan paint memerlukan waktu untuk dijalankan, dan jika tidak dikurangi, kita akan melebihi anggaran frame ~16 md. Pengguna akan menyadari bahwa kita melewatkan frame dan melihatnya sebagai jank, yang pada akhirnya berdampak buruk pada pengalaman pengguna aplikasi. Kita benar-benar tidak menginginkan itu, jadi mari kita lihat hal-hal apa yang menyebabkan pekerjaan paint diperlukan, dan apa yang dapat kita lakukan terkait hal itu.

Scroll

Setiap kali Anda men-scroll ke atas atau ke bawah di browser, konten tersebut perlu digambar ulang sebelum muncul di layar. Jika semuanya berjalan lancar, area tersebut hanya akan menjadi area kecil, tetapi meskipun demikian, elemen yang perlu digambar dapat menerapkan gaya yang kompleks. Jadi, hanya karena Anda memiliki area kecil untuk dicat, bukan berarti prosesnya akan cepat.

Untuk melihat area yang dicat ulang, Anda dapat menggunakan fitur “Tampilkan Persegi Panjang Cat” di DevTools Chrome (cukup tekan roda gigi kecil di pojok kanan bawah). Kemudian, dengan DevTools terbuka, cukup berinteraksi dengan halaman Anda dan Anda akan melihat persegi panjang berkedip yang menunjukkan tempat dan waktu Chrome mewarnai bagian halaman Anda.

Tampilkan Paint Rectangles di Chrome DevTools
Tampilkan Paint Rectangles di Chrome DevTools

Performa scroll sangat penting untuk keberhasilan situs Anda; pengguna benar-benar memperhatikan saat situs atau aplikasi Anda tidak dapat di-scroll dengan baik, dan mereka tidak menyukainya. Oleh karena itu, kita memiliki kepentingan untuk menjaga pekerjaan cat tetap ringan selama scroll sehingga pengguna tidak melihat jank.

Kami telah menulis artikel tentang performa scroll, jadi silakan baca jika Anda ingin mengetahui lebih lanjut detail performa scroll.

Interaksi

Interaksi adalah penyebab lain pekerjaan cat: pengarahan kursor, klik, sentuhan, tarik. Setiap kali pengguna melakukan salah satu interaksi tersebut, misalnya mengarahkan kursor, Chrome harus mengecat ulang elemen yang terpengaruh. Selain itu, seperti halnya scroll, jika ada gambar besar dan kompleks yang diperlukan, Anda akan melihat penurunan kecepatan frame.

Semua orang menginginkan animasi interaksi yang bagus dan lancar, jadi sekali lagi kita perlu melihat apakah gaya yang berubah dalam animasi menghabiskan terlalu banyak waktu.

Kombinasi yang tidak menguntungkan

Demo dengan cat mahal
Demo dengan cat mahal

Apa yang terjadi jika saya men-scroll dan kebetulan menggerakkan mouse secara bersamaan? Saya dapat secara tidak sengaja "berinteraksi" dengan elemen saat men-scroll melewatinya, sehingga memicu paint yang mahal. Hal ini, pada gilirannya, dapat mendorong saya melalui anggaran frame ~16,7 md (waktu yang harus kita pertahankan di bawahnya untuk mencapai 60 frame per detik). Saya telah membuat demo untuk menunjukkan maksud saya secara tepat. Mudah-mudahan saat Anda menggulir dan menggerakkan mouse, Anda akan melihat efek pengarahan kursor, tetapi mari kita lihat apa yang dilakukan Chrome DevTools:

DevTools Chrome menampilkan frame yang mahal
DevTools Chrome menampilkan frame yang mahal

Pada gambar di atas, Anda dapat melihat bahwa DevTools mendaftarkan pekerjaan cat saat saya mengarahkan kursor ke salah satu blok. Saya telah menggunakan beberapa gaya yang sangat berat dalam demo untuk menyampaikan poin, sehingga saya meningkatkan dan terkadang melampaui anggaran frame. Hal terakhir yang saya inginkan adalah harus melakukan pekerjaan cat ini tanpa perlu, dan terutama selama scroll saat ada pekerjaan lain yang harus dilakukan.

Jadi bagaimana kita bisa mencegah hal ini? Perbaikannya cukup mudah diterapkan. Triknya di sini adalah memasang pengendali scroll yang akan menonaktifkan efek pengarahan kursor dan menyetel timer untuk mengaktifkannya lagi. Artinya, kami menjamin bahwa saat Anda men-scroll, kami tidak perlu melakukan penggambaran interaksi yang mahal. Jika Anda berhenti cukup lama, kami menganggap aman untuk mengaktifkannya kembali.

Berikut kodenya:

// Used to track the enabling of hover effects
var enableTimer = 0;

/*
 * Listen for a scroll and use that to remove
 * the possibility of hover effects
 */
window.addEventListener('scroll', function() {
  clearTimeout(enableTimer);
  removeHoverClass();

  // enable after 1 second, choose your own value here!
  enableTimer = setTimeout(addHoverClass, 1000);
}, false);

/**
 * Removes the hover class from the body. Hover styles
 * are reliant on this class being present
 */
function removeHoverClass() {
  document.body.classList.remove('hover');
}

/**
 * Adds the hover class to the body. Hover styles
 * are reliant on this class being present
 */
function addHoverClass() {
  document.body.classList.add('hover');
}

Seperti yang dapat Anda lihat, kita menggunakan class pada isi untuk melacak apakah efek pengarahan kursor "diizinkan" atau tidak, dan gaya yang mendasarinya mengandalkan keberadaan class ini:

/* Expect the hover class to be on the body
 before doing any hover effects */
.hover .block:hover {
 
}

Selesai.

Kesimpulan

Performa rendering sangat penting bagi pengguna untuk menikmati aplikasi Anda, dan Anda harus selalu berusaha menjaga beban kerja cat di bawah 16 md. Untuk membantu Anda melakukannya, Anda harus berintegrasi menggunakan DevTools sepanjang proses pengembangan untuk mengidentifikasi dan memperbaiki bottleneck saat muncul.

Interaksi yang tidak disengaja, terutama pada elemen yang banyak menggunakan cat, dapat sangat mahal dan akan menurunkan performa rendering. Seperti yang telah Anda lihat, kita dapat menggunakan potongan kecil kode untuk memperbaikinya.

Lihat situs dan aplikasi Anda, apakah perlu sedikit perlindungan cat?