Membuat scroll sentuh cepat secara default

Dave Tapuska
Dave Tapuska

Kita tahu bahwa responsivitas scroll sangat penting untuk interaksi pengguna dengan situs di perangkat seluler, tetapi pemroses peristiwa sentuh sering kali menyebabkan masalah performa scroll yang serius. Chrome telah mengatasi hal ini dengan mengizinkan pemroses peristiwa sentuh menjadi pasif (meneruskan opsi {passive: true} ke addEventListener()) dan mengirimkan peristiwa pointer API. Ini adalah fitur yang bagus untuk mendorong konten baru ke dalam model yang tidak memblokir scroll, tetapi terkadang developer merasa sulit untuk memahami dan mengadopsinya.

Kami percaya bahwa web harus cepat secara default tanpa perlu memahami detail rumit tentang perilaku browser. Di Chrome 56, kami menetapkan pemroses sentuh ke pasif secara default jika hal tersebut paling sering cocok dengan niat developer. Kami yakin bahwa dengan melakukan hal ini, kami dapat sangat meningkatkan pengalaman pengguna sekaligus memiliki dampak negatif minimal pada situs.

Dalam kasus yang jarang terjadi, perubahan ini dapat menyebabkan scroll yang tidak diinginkan. Hal ini biasanya mudah diatasi dengan menerapkan gaya touch-action: none ke elemen tempat scroll tidak boleh terjadi. Baca terus untuk mengetahui detail, cara mengetahui apakah Anda terpengaruh, dan tindakan yang dapat Anda lakukan.

Latar belakang: Peristiwa yang Dapat Dibatalkan memperlambat halaman Anda

Jika Anda memanggil preventDefault() dalam peristiwa touchstart atau touchmove pertama, Anda akan mencegah scroll. Masalahnya adalah pemroses biasanya tidak akan memanggil preventDefault(), tetapi browser harus menunggu peristiwa selesai untuk memastikannya. "Pemroses peristiwa pasif" yang ditentukan developer akan mengatasi hal ini. Saat menambahkan peristiwa sentuh dengan objek {passive: true} sebagai parameter ketiga dalam pengendali peristiwa, Anda memberi tahu browser bahwa pemroses touchstart tidak akan memanggil preventDefault() dan browser dapat melakukan scroll dengan aman tanpa memblokir pemroses. Contoh:

window.addEventListener("touchstart", func, {passive: true} );

Intervensi

Motivasi utama kami adalah mengurangi waktu yang diperlukan untuk memperbarui tampilan setelah pengguna menyentuh layar. Untuk memahami penggunaan touchstart dan touchmove, kami menambahkan metrik untuk menentukan seberapa sering perilaku pemblokiran scroll terjadi.

Kami melihat persentase peristiwa sentuh yang dapat dibatalkan yang dikirim ke target root (jendela, dokumen, atau isi) dan menentukan bahwa sekitar 80% pemroses ini secara konseptual pasif, tetapi tidak terdaftar sebagai pasif. Mengingat skala masalah ini, kami melihat peluang besar untuk meningkatkan scroll tanpa tindakan developer apa pun dengan membuat peristiwa ini otomatis "pasif".

Hal ini mendorong kami untuk menentukan intervensi sebagai: jika target pemroses touchstart atau touchmove adalah window, document, atau body, kami menetapkan passive ke true secara default. Artinya, kode seperti:

window.addEventListener("touchstart", func);

menjadi setara dengan:

window.addEventListener("touchstart", func, {passive: true} );

Sekarang, panggilan ke preventDefault() di dalam pemroses akan diabaikan.

Grafik di bawah menunjukkan waktu yang diperlukan oleh 1% scroll teratas dari saat pengguna menyentuh layar untuk men-scroll hingga saat tampilan diperbarui. Data ini adalah untuk semua situs di Chrome untuk Android. Sebelum intervensi diaktifkan, 1% scroll hanya memerlukan waktu lebih dari 400 md. Sekarang, waktu tersebut telah dikurangi menjadi hanya lebih dari 250 md di Chrome 56 Beta; pengurangan sekitar 38%. Di masa mendatang, kami berharap dapat membuat passive true menjadi default untuk semua pemroses touchstart dan touchmove, sehingga menguranginya menjadi di bawah 50 md.

Grafik waktu scroll 1% teratas

Kerusakan dan Panduan

Dalam sebagian besar kasus, tidak akan ada kerusakan. Namun, jika kerusakan terjadi, gejala yang paling umum adalah scroll terjadi saat Anda tidak menginginkannya. Dalam kasus yang jarang terjadi, developer mungkin juga melihat peristiwa klik yang tidak terduga (saat preventDefault() tidak ada di pemroses touchend).

Di Chrome 56 dan yang lebih baru, DevTools akan mencatat peringatan saat Anda memanggil preventDefault() dalam peristiwa saat intervensi aktif.

touch-passive.html:19 Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080

Aplikasi Anda dapat menentukan apakah aplikasi mungkin mengalami hal ini di dunia nyata dengan memeriksa apakah memanggil preventDefault memiliki efek apa pun melalui properti defaultPrevented.

Kami mendapati bahwa sebagian besar halaman yang terpengaruh dapat diperbaiki dengan relatif mudah dengan menerapkan properti CSS touch-action jika memungkinkan. Jika Anda ingin mencegah semua scroll dan zoom browser dalam elemen, terapkan touch-action: none ke elemen tersebut. Jika Anda memiliki carousel horizontal, pertimbangkan untuk menerapkan touch-action: pan-y pinch-zoom ke carousel tersebut agar pengguna tetap dapat men-scroll secara vertikal dan melakukan zoom seperti biasa. Menerapkan tindakan sentuh dengan benar sudah diperlukan di browser seperti Edge desktop yang mendukung Peristiwa Pointer, bukan Peristiwa Sentuh. Untuk Safari seluler dan browser seluler lama yang tidak mendukung tindakan sentuh, pemroses sentuh Anda harus terus memanggil preventDefault meskipun akan diabaikan oleh Chrome.

Dalam kasus yang lebih kompleks, Anda mungkin juga perlu mengandalkan salah satu hal berikut:

  • Jika pemroses touchstart Anda memanggil preventDefault(), pastikan preventDefault() juga dipanggil dari pemroses touchend terkait untuk terus menekan pembuatan peristiwa klik dan perilaku ketuk default lainnya.
  • Terakhir (dan tidak dianjurkan) teruskan {passive: false} ke addEventListener() untuk mengganti perilaku default. Perhatikan bahwa Anda harus mendeteksi fitur jika Agen Pengguna mendukung EventListenerOptions.

Kesimpulan

Di Chrome 56, scroll dimulai jauh lebih cepat di banyak situs. Ini adalah satu-satunya dampak yang akan dilihat sebagian besar developer sebagai akibat dari perubahan ini. Dalam beberapa kasus, developer mungkin melihat scroll yang tidak disengaja.

Meskipun masih perlu dilakukan untuk Safari seluler, situs tidak boleh mengandalkan pemanggilan preventDefault() di dalam pemroses touchstart dan touchmove karena hal ini tidak lagi dijamin akan dihormati di Chrome. Developer harus menerapkan properti CSS touch-action pada elemen tempat scroll dan zoom harus dinonaktifkan untuk memberi tahu browser sebelum peristiwa sentuh terjadi. Untuk menyembunyikan perilaku default ketukan (seperti pembuatan peristiwa klik), panggil preventDefault() di dalam pemroses touchend.