Kaydırma duyarlılığının, kullanıcının mobil cihazlarda bir web sitesiyle etkileşimi için kritik olduğunu biliyoruz. Ancak dokunma etkinliği dinleyicileri genellikle ciddi kaydırma performansı sorunlarına neden oluyor. Chrome, dokunma etkinliği dinleyicilerinin pasif olmasına ({passive: true}
seçeneğini addEventListener()
'e ileterek) ve işaretçi etkinlikleri API'sini göndererek bu sorunu gidermektedir.
Bu özellikler, kaydırma işlemini engellemeyen modellere yeni içerikler eklemek için mükemmel olsa da geliştiriciler bazen bunları anlamakta ve uygulamakta zorlanıyor.
Web'in, geliştiricilerin tarayıcı davranışının ayrıntılarını anlamalarına gerek kalmadan varsayılan olarak hızlı olması gerektiğine inanıyoruz. Chrome 56'da, çoğu durumda geliştiricinin amacına uygun olduğunda dokunma işleyicilerini varsayılan olarak pasif olarak ayarlıyoruz. Bu sayede, siteleri en az düzeyde olumsuz etkilemekle birlikte kullanıcı deneyimini önemli ölçüde iyileştirebileceğimize inanıyoruz.
Bu değişiklik, nadir durumlarda istenmeyen kaydırmalara neden olabilir. Bu sorun genellikle, kaydırma işleminin gerçekleşmemesi gereken öğeye touch-action: none stili uygulanarak kolayca giderilebilir. Ayrıntılar, bu durumdan etkilenip etkilenmediğinizi nasıl anlayacağınız ve bu konuda neler yapabileceğiniz için okumaya devam edin.
Arka plan: İptal edilebilir etkinlikler sayfanızı yavaşlatır
touchstart
veya ilk touchmove
etkinliklerinde preventDefault() çağrısı yaparsanız kaydırmayı engellersiniz.
Sorun, dinleyicilerin çoğu zaman preventDefault()
çağrısını yapmamasıdır ancak tarayıcının bundan emin olmak için etkinliğin tamamlanmasını beklemesi gerekir.
Geliştirici tarafından tanımlanan "pasif etkinlik işleyiciler" bu sorunu çözer. Etkinlik işleyicinizde üçüncü parametre olarak {passive: true}
nesnesi içeren bir dokunma etkinliği eklediğinizde tarayıcıya, touchstart
dinleyicisinin preventDefault()
'yi çağırmayacağını ve tarayıcının dinleyiciyi engellemeden kaydırma işlemini güvenli bir şekilde gerçekleştirebileceğini bildirirsiniz. Örneğin:
window.addEventListener("touchstart", func, {passive: true} );
Müdahale
Ana amacımız, kullanıcı ekrana dokunduktan sonra ekranın güncellenmesi için geçen süreyi azaltmaktır. touchstart ve touchmove'un kullanımını anlamak için kaydırma engelleme davranışının ne sıklıkta gerçekleştiğini belirlemek üzere metrikler ekledik.
Bir kök hedefe (pencere, doküman veya gövde) gönderilen iptal edilebilir dokunma etkinliklerinin yüzdesine baktık ve bu işleyicilerin yaklaşık% 80'inin kavramsal olarak pasif olduğunu ancak bu şekilde kaydedilmediğini belirledik. Bu sorunun ölçeği göz önüne alındığında, bu etkinlikleri otomatik olarak "pasif" hale getirerek herhangi bir geliştirici işlemi yapmadan kaydırma özelliğini iyileştirmek için mükemmel bir fırsat olduğunu fark ettik.
Bu durum, müdahalemizi şu şekilde tanımlamamıza yol açtı: Bir touchstart veya touchmove dinleyicisinin hedefi window
, document
veya body
ise varsayılan olarak passive
'ı true
olarak ayarlıyoruz. Bu, aşağıdaki gibi kodların:
window.addEventListener("touchstart", func);
şuna eş değer olur:
window.addEventListener("touchstart", func, {passive: true} );
Artık dinleyici içinde preventDefault()
çağrıları yoksayılacak.
Aşağıdaki grafikte, kullanıcının ekrana dokunup kaydırmaya başladığı andan ekranın güncellendiği ana kadar geçen sürenin, kaydırma işlemlerinin% 1'inde ne kadar olduğu gösterilmektedir. Bu veriler, Android için Chrome'daki tüm web siteleri içindir. Müdahale etkinleştirilmeden önce, kaydırma işlemlerinin% 1'i 400 ms'den biraz daha uzun sürüyordu. Bu süre, Chrome 56 Beta'da yaklaşık %38 oranında azaltılarak 250 ms'in biraz üzerine çekildi. Gelecekte, tüm touchstart
ve touchmove
dinleyicileri için varsayılan olarak pasif değerini doğru olarak ayarlayarak bu süreyi 50 ms'nin altına indirmeyi umuyoruz.

Hasar ve Rehberlik
Çoğu durumda, herhangi bir kesinti görülmez. Ancak bağlantı koptuğunda en yaygın belirti, istemediğiniz halde ekranın kaymasıdır. Nadiren de olsa geliştiriciler beklenmedik tıklama etkinlikleri de fark edebilir (preventDefault()
, touchend
dinleyicisinde eksik olduğunda).
Chrome 56 ve sonraki sürümlerde, müdahalenin etkin olduğu bir etkinlikte preventDefault()
işlevini çağırdığınızda DevTools bir uyarı günlüğe kaydeder.
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
Uygulamanız, preventDefault
çağrısının defaultPrevented
mülkü aracılığıyla herhangi bir etkisi olup olmadığını kontrol ederek bu sorunla karşılaşıp karşılaşmadığını belirleyebilir.
Etkilenen sayfaların büyük çoğunluğunun, mümkün olduğunda touch-action CSS özelliği uygulanarak nispeten kolay bir şekilde düzeltilebileceğini tespit ettik. Bir öğedeki tüm tarayıcı kaydırma ve yakınlaştırma işlemlerini engellemek istiyorsanız öğeye touch-action: none
uygulayın. Yatay bir bantınız varsa kullanıcının dikey olarak kaydırmaya ve yakınlaştırmaya devam edebilmesi için touch-action: pan-y pinch-zoom
öğesini uygulamayı düşünebilirsiniz. Dokunma işlemini doğru şekilde uygulamak, masaüstü Edge gibi Dokunma Etkinlikleri'ni değil İşaretçi Etkinlikleri'ni destekleyen tarayıcılarda zaten gereklidir. Dokunma işlemini desteklemeyen mobil Safari ve eski mobil tarayıcılarda, dokunma dinleyicilerinizin Chrome tarafından yoksayılacak olsa bile preventDefault
çağrısını yapmaya devam etmesi gerekir.
Daha karmaşık durumlarda aşağıdakilerden birini de kullanmanız gerekebilir:
touchstart
dinleyicinizpreventDefault()
'u çağırıyorsa tıklama etkinliklerinin ve diğer varsayılan dokunma davranışlarının oluşturulmasını engellemeye devam etmek için ilişkili touchend dinleyicilerinden preventDefault() işlevinin de çağrıldığından emin olun.- Varsayılan davranışı geçersiz kılmak için son (ve önerilmez) olarak
{passive: false}
öğesini addEventListener() işlevine iletin. Kullanıcı aracısının EventListenerOptions özelliğini destekleyip desteklemediğini tespit etmeniz gerektiğini unutmayın.
Sonuç
Chrome 56'da, birçok web sitesinde kaydırma işlemi önemli ölçüde daha hızlı başlar. Çoğu geliştirici, bu değişikliğin yalnızca bu etkisini fark edecektir. Bazı durumlarda geliştiriciler istenmeyen kaydırma hareketleri fark edebilir.
Mobil Safari için bunu yapmaya devam etmek gerekse de web siteleri, Chrome'da artık bu işlemin desteklenmeyeceğinden touchstart
ve touchmove
dinleyicilerinin içinde preventDefault()
çağrısına güvenmemelidir. Geliştiriciler, herhangi bir dokunma etkinliği gerçekleşmeden önce tarayıcıyı bilgilendirmek için kaydırma ve yakınlaştırmanın devre dışı bırakılması gereken öğelere touch-action
CSS özelliğini uygulamalıdır.
Dokunmanın varsayılan davranışını (ör. tıklama etkinliği oluşturma) engellemek için bir touchend
işleyici içinde preventDefault()
işlevini çağırın.