हम जानते हैं कि मोबाइल पर किसी वेबसाइट के साथ उपयोगकर्ता के जुड़ाव के लिए, स्क्रॉल करने की सुविधा का तेज़ी से काम करना ज़रूरी है. हालांकि, टच इवेंट के लिसनर की वजह से, अक्सर स्क्रॉल करने की परफ़ॉर्मेंस से जुड़ी गंभीर समस्याएं आती हैं. Chrome ने इस समस्या को हल करने के लिए, टच इवेंट के लिसनर को पैसिव ({passive: true}
विकल्प को addEventListener()
पर पास करना) और पॉइंटर इवेंट एपीआई को शिप करने की अनुमति दी है.
ये सुविधाएं, ऐसे मॉडल में नया कॉन्टेंट जोड़ने के लिए बेहतरीन हैं जो स्क्रोल करने पर रुकते नहीं हैं. हालांकि, डेवलपर को इन्हें समझने और इस्तेमाल करने में कभी-कभी मुश्किल होती है.
हमारा मानना है कि वेब डिफ़ॉल्ट रूप से तेज़ होना चाहिए. इसके लिए, डेवलपर को ब्राउज़र के काम करने के तरीके की बारीकियों को समझने की ज़रूरत नहीं होती. Chrome 56 में, हम टच लिसनर को डिफ़ॉल्ट रूप से पैसिव पर सेट कर रहे हैं. ऐसा उन मामलों में किया जा रहा है जहां यह सेटिंग, डेवलपर के मकसद से मेल खाती है. हमारा मानना है कि ऐसा करने से, हम साइटों पर कम से कम असर डालते हुए, उपयोगकर्ताओं के अनुभव को बेहतर बना सकते हैं.
हालांकि, कुछ मामलों में ऐसा हो सकता है कि इस बदलाव की वजह से, अनचाहे तौर पर स्क्रोल हो जाए. आम तौर पर, touch-action: none स्टाइल को उस एलिमेंट पर लागू करके, इस समस्या को आसानी से हल किया जा सकता है जहां स्क्रोल नहीं होना चाहिए. ज़्यादा जानकारी के लिए पढ़ें. साथ ही, जानें कि आप पर इसका असर पड़ा है या नहीं और इस बारे में क्या किया जा सकता है.
बैकग्राउंड: रद्द किए जा सकने वाले इवेंट की वजह से आपके पेज की स्पीड कम हो जाती है
अगर touchstart
या पहले touchmove
इवेंट में preventDefault() को कॉल किया जाता है, तो स्क्रोल करने की सुविधा बंद हो जाएगी.
समस्या यह है कि ज़्यादातर मामलों में, दर्शक preventDefault()
को कॉल नहीं करेंगे. हालांकि, ब्राउज़र को इस बात की पुष्टि करने के लिए, इवेंट के खत्म होने का इंतज़ार करना होगा.
डेवलपर के तय किए गए "पैसिव इवेंट लिसनर" से यह समस्या हल हो जाती है. जब इवेंट हैंडलर में तीसरे पैरामीटर के तौर पर {passive: true}
ऑब्जेक्ट के साथ टच इवेंट जोड़ा जाता है, तो इसका मतलब है कि ब्राउज़र को यह बताया जा रहा है कि touchstart
लिसनर, preventDefault()
को कॉल नहीं करेगा. साथ ही, ब्राउज़र लिसनर को ब्लॉक किए बिना, सुरक्षित तरीके से स्क्रोल कर सकता है. उदाहरण के लिए:
window.addEventListener("touchstart", func, {passive: true} );
द इंटरवेंशन
हमारा मुख्य मकसद, उपयोगकर्ता के स्क्रीन को छूने के बाद डिसप्ले को अपडेट होने में लगने वाले समय को कम करना है. touchstart और touchmove के इस्तेमाल को समझने के लिए, हमने मेट्रिक जोड़ी हैं. इससे यह पता चलता है कि स्क्रोल ब्लॉक करने वाला व्यवहार कितनी बार हुआ.
हमने रॉट टारगेट (विंडो, दस्तावेज़ या बॉडी) पर भेजे गए रद्द किए जा सकने वाले टच इवेंट का प्रतिशत देखा. इससे पता चला कि इनमें से करीब 80% लिसनर सैद्धांतिक तौर पर पैसिव हैं, लेकिन इन्हें इस तरह से रजिस्टर नहीं किया गया था. इस समस्या के दायरे को देखते हुए, हमें इन इवेंट को अपने-आप "पैसिव" बनाकर, डेवलपर की कार्रवाई के बिना स्क्रोलिंग को बेहतर बनाने का एक शानदार मौका मिला.
इस वजह से, हमने अपने इंटरवेंशन को इस तरह से तय किया है: अगर touchstart या
touchmove listener का टारगेट window
, document
या body
है, तो हम passive
को डिफ़ॉल्ट रूप से true
पर सेट कर देते हैं. इसका मतलब है कि इस तरह का कोड:
window.addEventListener("touchstart", func);
यह इसकी बराबर हो जाती है:
window.addEventListener("touchstart", func, {passive: true} );
अब लिसनर में preventDefault()
को किए जाने वाले कॉल को अनदेखा कर दिया जाएगा.
नीचे दिए गए ग्राफ़ में, सबसे ज़्यादा 1% स्क्रोल के लिए लगने वाला समय दिखाया गया है. इसमें, उपयोगकर्ता के स्क्रीन को स्क्रोल करने के लिए छूने से लेकर, डिसप्ले के अपडेट होने तक का समय शामिल है. यह डेटा, Chrome for Android में मौजूद सभी वेबसाइटों के लिए है. इंटरवेंशन चालू होने से पहले, स्क्रॉल करने में 1% से ज़्यादा समय लगा. अब यह समय, Chrome 56 बीटा वर्शन में 250 मिलीसेकंड से ज़्यादा हो गया है. इसमें करीब 38% की कमी आई है. आने वाले समय में, हम उम्मीद करते हैं कि touchstart
और touchmove
के सभी दर्शकों के लिए, डिफ़ॉल्ट रूप से पैसिव ट्रांसकोडिंग की सुविधा चालू रहेगी. इससे, ट्रांसकोडिंग में लगने वाला समय 50 मिलीसेकंड से भी कम हो जाएगा.

ब्रेकेज और दिशा-निर्देश
ज़्यादातर मामलों में, कोई रुकावट नहीं आएगी. हालांकि, जब ब्रेकेज होता है, तो सबसे आम लक्षण यह होता है कि जब आपको स्क्रीन पर स्क्रोल नहीं करना होता, तब भी स्क्रोल हो जाता है. कुछ मामलों में, डेवलपर को अनचाहे क्लिक इवेंट भी दिख सकते हैं
(जब touchend
लिसनर में preventDefault()
मौजूद न हो).
Chrome 56 और उसके बाद के वर्शन में, किसी ऐसे इवेंट में
preventDefault()
को कॉल करने पर DevTools चेतावनी को लॉग करेगा जिसमें इंटरवेंशन चालू है.
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
आपका ऐप्लिकेशन यह तय कर सकता है कि क्या यह समस्या असल में आ रही है या नहीं. इसके लिए, यह देखा जाता है कि preventDefault
को कॉल करने से, defaultPrevented
प्रॉपर्टी पर कोई असर पड़ा है या नहीं.
हमें पता चला है कि जिन पेजों पर असर पड़ा है उनमें से ज़्यादातर पेजों को आसानी से ठीक किया जा सकता है. इसके लिए, जहां भी हो सके वहां touch-action CSS प्रॉपर्टी लागू करें. अगर आपको किसी एलिमेंट में ब्राउज़र के स्क्रोल और ज़ूम करने की सुविधा को बंद करना है, तो उस पर touch-action: none
लागू करें. अगर आपके पास कोई हॉरिज़ॉन्टल कैरसेल है, तो उस पर touch-action: pan-y pinch-zoom
लागू करें, ताकि उपयोगकर्ता अब भी वर्टिकल तौर पर स्क्रोल कर सके और सामान्य तरीके से ज़ूम कर सके. touch-action को सही तरीके से लागू करना, डेस्कटॉप Edge जैसे ब्राउज़र पर पहले से ही ज़रूरी है. ये ब्राउज़र, टच इवेंट के बजाय पॉइंटर इवेंट के साथ काम करते हैं. मोबाइल Safari और उन पुराने मोबाइल ब्राउज़र के लिए जो टच ऐक्शन के साथ काम नहीं करते, आपके टच ऑडियंस को preventDefault
को कॉल करना जारी रखना चाहिए. भले ही, Chrome इसे अनदेखा कर दे.
ज़्यादा मुश्किल मामलों में, इनमें से किसी एक पर भी भरोसा करना पड़ सकता है:
- अगर आपका
touchstart
लिस्नरpreventDefault()
को कॉल करता है, तो पक्का करें कि क्लिक इवेंट और टैप करने पर होने वाली अन्य डिफ़ॉल्ट कार्रवाइयों को रोकने के लिए, preventDefault() को भी टचएंड लिस्नर से कॉल किया जाए. - डिफ़ॉल्ट व्यवहार को बदलने के लिए, addEventListener() में
{passive: false}
को आखिरी (और इसे इस्तेमाल करने का सुझाव नहीं दिया जाता) पास करें. ध्यान रखें कि आपको यह पता लगाना होगा कि उपयोगकर्ता एजेंट, EventListenerOptions के साथ काम करता है या नहीं.
नतीजा
Chrome 56 में, कई वेबसाइटों पर स्क्रोल करने की सुविधा काफ़ी तेज़ी से शुरू होती है. इस बदलाव से, ज़्यादातर डेवलपर पर सिर्फ़ यही असर पड़ेगा. कुछ मामलों में, डेवलपर को अनचाहे स्क्रोल होने की समस्या दिख सकती है.
हालांकि, मोबाइल Safari के लिए अब भी ऐसा करना ज़रूरी है, लेकिन वेबसाइटों को touchstart
और touchmove
के अंदर preventDefault()
को कॉल करने पर भरोसा नहीं करना चाहिए, क्योंकि अब यह पक्का नहीं है कि Chrome में ऐसा किया जा सकेगा. डेवलपर को उन एलिमेंट पर touch-action
सीएसएस प्रॉपर्टी लागू करनी चाहिए जहां स्क्रोल और ज़ूम करने की सुविधा बंद होनी चाहिए. इससे, किसी भी टच इवेंट से पहले ब्राउज़र को सूचना मिल जाएगी.
टैप के डिफ़ॉल्ट व्यवहार को रोकने के लिए, touchend
listener में preventDefault()
को कॉल करें. जैसे, क्लिक इवेंट जनरेट करना.