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.

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 memanggilpreventDefault()
, 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
.