Menghindari cat yang tidak perlu

Pengantar

Menggambar elemen untuk situs atau aplikasi bisa menjadi sangat mahal, dan dapat berdampak negatif pada performa runtime kita. Dalam artikel ini, kita melihat sekilas apa yang dapat memicu pengecatan di browser, dan bagaimana Anda dapat mencegah terjadinya paint yang tidak perlu.

Lukisan: Tur singkat

Salah satu tugas utama yang harus dilakukan browser adalah mengubah DOM dan CSS menjadi piksel pada layar, dan melakukannya melalui proses yang cukup kompleks. Dimulai dengan membaca markup dan dari sini membuat hierarki DOM. Ia melakukan hal serupa dengan CSS dan dari situlah membuat WebView. DOM dan Keystore kemudian digabungkan dan, akhirnya, kita sampai pada struktur yang memungkinkan kita untuk mulai melukis beberapa piksel.

Proses menggambarnya sendiri menarik. Di Chrome, hierarki gabungan DOM dan CSS diraster oleh beberapa software yang disebut Skia. Jika Anda pernah bermain dengan elemen canvas, Skia's API akan terlihat sangat familier bagi Anda; ada banyak fungsi bergaya moveTo dan lineTo serta banyak fungsi lanjutan. Pada dasarnya, semua elemen yang perlu dilukis disaring ke kumpulan panggilan Skia yang dapat dieksekusi, dan outputnya merupakan sekumpulan bitmap. Bitmap ini diupload ke GPU, dan GPU membantu dengan menyusunnya bersama untuk memberi kita gambar akhir di layar.

Dom ke piksel

Hal yang perlu diperhatikan adalah beban kerja Skia dipengaruhi secara langsung oleh gaya yang Anda terapkan pada elemen. Jika Anda menggunakan gaya yang banyak menggunakan algoritma, Skia akan memiliki lebih banyak pekerjaan yang harus dilakukan. Colt McAnlis telah menulis artikel tentang bagaimana CSS memengaruhi bobot render halaman, jadi Anda harus membacanya untuk mendapatkan lebih banyak insight.

Meskipun demikian, pekerjaan cat membutuhkan waktu untuk dilakukan, dan jika kita tidak menguranginya, kita akan melebihi anggaran frame sebesar ~16 milidetik. Pengguna akan menyadari bahwa kita melewatkan frame dan melihatnya sebagai jank, yang pada akhirnya berdampak buruk pada pengalaman pengguna aplikasi kita. Kami benar-benar tidak menginginkannya, jadi mari kita lihat hal apa yang menyebabkan pekerjaan menggambar diperlukan, dan apa yang dapat kita lakukan terkait hal itu.

Scroll

Setiap kali Anda men-scroll ke atas atau ke bawah di browser, konten perlu digambar ulang sebelum muncul di layar. Semua yang baik itu hanya akan menjadi area kecil, tetapi bahkan jika itu terjadi, elemen yang perlu digambar bisa menerapkan gaya yang kompleks. Jadi hanya karena Anda memiliki area yang kecil untuk dicat, bukan berarti hal itu akan terjadi dengan cepat.

Untuk melihat area apa yang dicat ulang, Anda bisa menggunakan fitur "Show Paint Rectangles" di Chrome DevTools (cukup tekan roda gigi kecil di sudut kanan bawah). Lalu, saat DevTools terbuka, cukup berinteraksilah dengan halaman Anda dan Anda akan melihat persegi panjang yang berkedip menunjukkan di mana dan kapan Chrome menggambar bagian dari halaman Anda.

Menampilkan Persegi Panjang Cat di Chrome DevTools
Menampilkan Persegi Panjang Cat di Chrome DevTools

Kinerja pengguliran sangat penting untuk keberhasilan situs; pengguna benar-benar memperhatikan ketika situs atau aplikasi Anda tidak dapat digulir dengan baik, dan mereka tidak menyukainya. Oleh karena itu, kami memiliki kepentingan untuk menjaga agar pekerjaan cat tetap ringan selama scroll sehingga pengguna tidak melihat jank.

Sebelumnya, saya telah menulis artikel tentang performa scroll, jadi lihatlah jika Anda ingin mengetahui lebih lanjut tentang spesifikasi performa scroll.

Interaksi

Interaksi adalah penyebab lain dari pekerjaan menggambar: pengarahan kursor, klik, sentuhan, seret. Setiap kali pengguna melakukan salah satu interaksi tersebut, katakanlah mengarahkan kursor, maka Chrome harus melukis ulang elemen yang terpengaruh. Sama seperti halnya scrolling, jika Anda memerlukan paint yang besar dan kompleks, Anda akan melihat penurunan kecepatan frame.

Semua orang menginginkan animasi interaksi yang bagus, halus, dan harus dilihat lagi 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 menggulir dan kebetulan menggerakkan mouse di saat yang sama? Saya dapat secara tidak sengaja "berinteraksi" dengan elemen saat saya men-scroll melewatinya, sehingga memicu cat yang mahal. Hal itu, pada akhirnya, dapat mendorong saya mencapai anggaran frame ~16,7 md (waktu yang kita harus tetap di bawah itu untuk mencapai 60 frame per detik). Saya telah membuat demo untuk menunjukkan kepada Anda apa yang saya maksud. Mudah-mudahan saat Anda menggulir dan menggerakkan mouse, Anda akan melihat efek arahkan kursor, tetapi mari kita lihat apa yang dilakukan oleh DevTools Chrome:

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

Pada gambar di atas, Anda bisa melihat bahwa DevTools mendaftarkan pekerjaan menggambar saat saya mengarahkan kursor ke salah satu blok. Saya telah menggunakan beberapa gaya yang sangat rumit dalam demo untuk menegaskan, jadi saya mendorong hingga dan kadang-kadang melalui anggaran frame saya. Hal terakhir yang saya inginkan adalah melakukan pekerjaan mengecat ini dengan cara yang tidak perlu, terutama selama scroll ketika ada pekerjaan lain yang harus dilakukan.

Jadi bagaimana kita bisa menghentikan hal ini agar tidak terjadi? Ketika terjadi, perbaikannya cukup mudah untuk diimplementasikan. Triknya di sini adalah dengan memasang pengendali scroll yang akan menonaktifkan efek pengarahan kursor dan menyetel timer untuk mengaktifkannya lagi. Itu berarti, kami menjamin bahwa saat Anda men-scroll, kami tidak perlu melakukan paint interaksi yang mahal. Jika Anda sudah berhenti cukup lama, kami rasa 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", dan gaya yang mendasarinya bergantung pada keberadaan class ini:

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

Dan itu saja!

Kesimpulan

Performa rendering sangat penting bagi pengguna yang menikmati aplikasi Anda, dan Anda harus selalu berusaha menjaga beban kerja paint Anda di bawah 16 md. Untuk membantu melakukannya, Anda harus mengintegrasikan menggunakan DevTools selama proses pengembangan untuk mengidentifikasi dan mengatasi bottleneck yang muncul.

Interaksi yang tidak disengaja, khususnya pada elemen yang penuh dengan cat, bisa sangat mahal dan akan mengganggu performa rendering. Seperti yang Anda lihat, kita dapat menggunakan sepotong kecil kode untuk memperbaikinya.

Lihat situs dan aplikasi Anda, yang dapat mereka lakukan dengan sedikit perlindungan cat?