डिफ़ॉल्ट रूप से, टच को तेज़ी से स्क्रोल करने की सुविधा चालू करना

डेव तापुस्का
डेव तापुस्का

हम जानते हैं कि मोबाइल पर किसी वेबसाइट पर, उपयोगकर्ता के जुड़ाव के लिए स्क्रोल करते समय रिस्पॉन्स देना बहुत ज़रूरी होता है. फिर भी, टच इवेंट लिसनर की वजह से, अक्सर स्क्रोल करने पर परफ़ॉर्मेंस में गंभीर समस्याएं आती हैं. Chrome इस समस्या को ठीक कर रहा है. इसके लिए, वह टच इवेंट लिसनर को पैसिव ({passive: true} विकल्प को addEventListener() में पास करके) और पॉइंटर इवेंट एपीआई को भेजने की अनुमति दे रहा है. नए कॉन्टेंट को ऐसे मॉडल में ले जाने के लिए ये शानदार सुविधाएं हैं जो स्क्रोल करने की प्रोसेस को ब्लॉक नहीं करती हैं. हालांकि, कभी-कभी डेवलपर के लिए इन्हें समझना और इस्तेमाल करना मुश्किल होता है.

हमारा मानना है कि डिफ़ॉल्ट रूप से वेब की स्पीड तेज़ होनी चाहिए. इसके लिए, डेवलपर को ब्राउज़र के काम करने के तरीके की बारीक जानकारी को समझने की ज़रूरत नहीं होनी चाहिए. Chrome 56 में, हम उन मामलों में लिसनर को डिफ़ॉल्ट रूप से पैसिव पर सेट करते हैं जहां यह अक्सर डेवलपर के मकसद से मेल खाता है. हमारा मानना है कि ऐसा करके उपयोगकर्ताओं के अनुभव को बेहतर बनाया जा सकता है, साथ ही साइटों पर कम से कम बुरा असर पड़ सकता है.

कुछ मामलों में, इस बदलाव की वजह से अनचाहे तरीके से स्क्रोल किया जा सकता है. आम तौर पर, टच-ऐक्शन: कोई नहीं स्टाइल को एलिमेंट पर लागू करके, इसे आसानी से ठीक किया जा सकता है. जहां स्क्रोलिंग नहीं होनी चाहिए. इस बारे में ज़्यादा जानने के लिए आगे पढ़ें. यहां यह भी बताया गया है कि क्या किसी समस्या का आप पर असर हुआ है या नहीं और इस बारे में क्या किया जा सकता है.

बैकग्राउंड: रद्द किए जा सकने वाले इवेंट की वजह से, आपके पेज की परफ़ॉर्मेंस धीमी हो जाती है

अगर touchstart या पहले touchmove इवेंट में preventDefault() को कॉल किया जाता है, तो स्क्रोल नहीं किया जा सकेगा. समस्या यह है कि ज़्यादातर लोग preventDefault() को कॉल नहीं करेंगे, लेकिन इसके लिए ब्राउज़र को इवेंट खत्म होने का इंतज़ार करना होगा. डेवलपर के तय किए गए "पैसिव इवेंट लिसनर" की मदद से, इस समस्या को हल किया जा सकता है. जब इवेंट हैंडलर में तीसरे पैरामीटर के तौर पर, {passive: true} ऑब्जेक्ट के साथ एक टच इवेंट जोड़ा जाता है, तब ब्राउज़र को बताया जाता है कि touchstart लिसनर preventDefault() को कॉल नहीं करेगा. साथ ही, ब्राउज़र लिसनर को ब्लॉक किए बिना, सुरक्षित तरीके से स्क्रोल कर सकता है. उदाहरण के लिए:

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

द इंटरवेंशन

हमारा मुख्य मकसद है कि उपयोगकर्ता के स्क्रीन छूने के बाद, डिसप्ले को अपडेट होने में लगने वाला समय कम हो. Touchstart और Touchmove के इस्तेमाल को समझने के लिए, हमने मेट्रिक जोड़ी हैं. इनसे यह तय किया जा सकता है कि स्क्रोल करने पर रोक कितनी बार लगाई गई है.

हमने रूट टारगेट (विंडो, दस्तावेज़ या मुख्य भाग) पर भेजे गए ऐसे टच इवेंट के प्रतिशत पर गौर किया जिन्हें रद्द किया जा सकता था. हमें पता चला कि इनमें से करीब 80% लोग सैद्धांतिक रूप से काम नहीं करते थे, लेकिन उन्हें इस तरह रजिस्टर नहीं किया गया था. इस समस्या को देखते हुए हमने पाया कि डेवलपर की ओर से कार्रवाई किए बिना, स्क्रोल करने की सुविधा को बेहतर बनाया जा सकता है. इसके लिए, इन इवेंट को अपने-आप "पैसिव" बनाना ज़रूरी है.

इससे हमें अपने इंटरवेंशन को इस तरह से परिभाषित करने में मदद मिली: अगर किसी टचपॉइंट या टचपॉइंट का टारगेट window, document या body है, तो हम डिफ़ॉल्ट रूप से passive को true पर सेट करते हैं. इसका मतलब है कि कोड:

window.addEventListener("touchstart", func);

इसके बराबर हो जाता है:

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

अब लिसनर में मौजूद preventDefault() को किए जाने वाले कॉल को अनदेखा कर दिया जाएगा.

नीचे दिया गया ग्राफ़, स्क्रोल करने में लगने वाला समय दिखाता है. इसमें, उपयोगकर्ता के स्क्रीन को छूने से लेकर डिसप्ले के अपडेट होने तक, स्क्रोल करने में लगने वाला समय दिखता है. यह डेटा Android के लिए Chrome में सभी वेबसाइटों के लिए है. इंटरवेंशन को चालू करने से पहले, एक प्रतिशत स्क्रोल को 400 मि॰से॰ से ज़्यादा समय लगा. Chrome 56 के बीटा वर्शन में यह अब सिर्फ़ 250 मि॰से॰ से कम हो गया है. इसमें करीब 38% की कमी आई है. हम चाहते हैं कि आने वाले समय में, touchstart और touchmove सुनने वाले सभी लोगों के लिए पैसिव ट्रू को डिफ़ॉल्ट तौर पर इस्तेमाल किया जा सके. इससे यह संख्या 50 मि॰से॰ से कम हो जाएगी.

स्रोल समय के दौरान, सबसे ज़्यादा देखे गए 1% समय का ग्राफ़

ब्रेकेज और सलाह

ज़्यादातर मामलों में, किसी भी तरह की गड़बड़ी का पता नहीं चलता. हालांकि, ब्रेकेज होने पर, इसका सबसे आम लक्षण यह है कि न चाहते हुए भी स्क्रोल किया जा सकता है. कभी-कभी ऐसा भी हो सकता है कि डेवलपर को अनचाहे क्लिक इवेंट (जब 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: none लागू करें. अगर आपके पास हॉरिज़ॉन्टल कैरसेल है, तो touch-action: pan-y pinch-zoom को लागू करने पर विचार करें, ताकि उपयोगकर्ता अब भी वर्टिकल तरीके से स्क्रोल कर सके और सामान्य तरीके से ज़ूम कर सके. डेस्कटॉप EDGE जैसे ब्राउज़र पर टच-ऐक्शन को सही तरीके से लागू करना पहले से ही ज़रूरी है. यह सुविधा पॉइंटर इवेंट के साथ काम करती है, न कि टच इवेंट के साथ. मोबाइल Safari और ऐसे पुराने मोबाइल ब्राउज़र के लिए जो टच-ऐक्शन की सुविधा नहीं देतेpreventDefault

ज़्यादा जटिल मामलों में, इनमें से किसी एक पर भरोसा करना ज़रूरी हो सकता है:

  • अगर आपका touchstart लिसनर preventDefault() को कॉल करता है, तो पक्का करें कि preventDefault() को इससे जुड़े टचएंड लिसनर से कॉल किया जाता है, ताकि क्लिक इवेंट की जनरेशन और टैप करने के अन्य डिफ़ॉल्ट व्यवहार को रोका जा सके.
  • डिफ़ॉल्ट व्यवहार को बदलने के लिए, addEventListener() में आखिरी बार {passive: false} पास करें. हालांकि, ऐसा करने की सलाह नहीं दी जाती. ध्यान रखें, आपको यह पता लगाना होगा कि उपयोगकर्ता एजेंट, EventListenerOptions के साथ काम करता है या नहीं.

नतीजा

Chrome 56 में, कई वेबसाइटों पर स्क्रोलिंग काफ़ी तेज़ी से शुरू होती है. इस बदलाव के चलते, ज़्यादातर डेवलपर को सिर्फ़ यही असर दिखेगा. कुछ मामलों में, डेवलपर को अनजाने में स्क्रोल करने के बारे में पता चल सकता है.

हालांकि, मोबाइल Safari के लिए अब भी ऐसा करना ज़रूरी है, फिर भी वेबसाइटों को touchstart और touchmove सुनने वालों में से preventDefault() को कॉल करने पर भरोसा नहीं करना चाहिए, क्योंकि अब Chrome में इस सुविधा पर ध्यान देने की गारंटी नहीं है. डेवलपर को उन एलिमेंट पर touch-action सीएसएस प्रॉपर्टी लागू करनी चाहिए जहां स्क्रोल और ज़ूम करने की सुविधा बंद होनी चाहिए. इससे, किसी भी टच इवेंट से पहले ब्राउज़र को सूचना दी जा सकेगी. किसी टैप के डिफ़ॉल्ट व्यवहार को रोकने के लिए (जैसे, क्लिक इवेंट का जनरेट होना), touchend लिसनर में preventDefault() को कॉल करें.