कम शब्दों में कहा जाए तो
- Chrome 60, इवेंट की फ़्रीक्वेंसी कम करके, jank को कम करता है. इससे फ़्रेम टाइमिंग की स्थिरता बेहतर होती है.
- Chrome 58 में पेश किए गए
getCoalescedEvents()
तरीके से, इवेंट की वही जानकारी मिलती है जो पहले मिलती थी.
वेब पर उपयोगकर्ता को बेहतर अनुभव देना ज़रूरी है. इनपुट इवेंट मिलने और विज़ुअल के अपडेट होने के बीच का समय अहम होता है. साथ ही, आम तौर पर कम काम करना ज़रूरी होता है. Chrome के पिछले कुछ वर्शन में, हमने इन डिवाइसों पर इनपुट लैटेंसी को कम किया है.
Chrome 60 में, हम एक बदलाव कर रहे हैं. इससे, ब्राउज़िंग को बेहतर बनाने और परफ़ॉर्मेंस को बेहतर बनाने में मदद मिलेगी. इस बदलाव की वजह से, ये इवेंट कम फ़्रीक्वेंसी पर होंगे. साथ ही, दी गई जानकारी ज़्यादा बेहतर होगी. Jelly Bean रिलीज़ होने के बाद, Android पर इनपुट को अलाइन करने वाला Choreographer उपलब्ध कराया गया था. ठीक उसी तरह, हम सभी प्लैटफ़ॉर्म पर वेब पर फ़्रेम अलाइन करने वाला इनपुट उपलब्ध करा रहे हैं.
हालांकि, कभी-कभी आपको ज़्यादा इवेंट की ज़रूरत पड़ती है. इसलिए, हमने Chrome 58 में, getCoalescedEvents()
नाम का एक तरीका लागू किया है. इसकी मदद से, आपके ऐप्लिकेशन को पॉइंटर का पूरा पाथ तब भी मिल सकता है, जब उसे कम इवेंट मिल रहे हों.
सबसे पहले, इवेंट की फ़्रीक्वेंसी के बारे में बात करते हैं.
इवेंट की फ़्रीक्वेंसी कम करना
आइए, कुछ बुनियादी बातें समझते हैं: टच-स्क्रीन 60-120Hz पर इनपुट देती हैं और माउस आम तौर पर 100Hz पर इनपुट देते हैं. हालांकि, यह 2000Hz तक भी हो सकता है. हालांकि, किसी मॉनिटर की सामान्य रीफ़्रेश दर 60 हर्ट्ज़ होती है. इसका क्या मतलब है? इसका मतलब है कि हमें इनपुट की दर, डिसप्ले को अपडेट करने की दर से ज़्यादा होती है. इसलिए, चलिए devtools में जाकर, कैनवस वाले पेंटिंग ऐप्लिकेशन की परफ़ॉर्मेंस की टाइमलाइन देखें.
नीचे दी गई इमेज में, requestAnimationFrame()
-अलाइन किए गए इनपुट के बंद होने पर, आपको हर फ़्रेम में अलग-अलग फ़्रेम टाइम के साथ कई प्रोसेसिंग ब्लॉक दिख सकते हैं.
छोटे पीले ब्लॉक, हिट टेस्टिंग के बारे में बताते हैं. जैसे, डीओएम इवेंट का टारगेट, इवेंट डिस्पैच करना, JavaScript चलाना, कर्सर घुमाने पर दिखने वाले नोड को अपडेट करना, और लेआउट और स्टाइल का फिर से हिसाब लगाना.
तो हम ऐसा अतिरिक्त काम क्यों कर रहे हैं जिससे विज़ुअल में कोई अपडेट नहीं होता? आम तौर पर, हम ऐसा कोई भी काम नहीं करना चाहते जिससे उपयोगकर्ता को फ़ायदा न हो. Chrome 60 से, इनपुट पाइपलाइन लगातार होने वाले इवेंट (wheel
,
mousewheel
,
touchmove
,
pointermove
,
mousemove
) को डिस्पैच करने में देरी करेगी. साथ ही, इन्हें requestAnimationFrame()
कॉलबैक होने से ठीक पहले डिस्पैच करेगी. नीचे दी गई इमेज में (इसमें सुविधा चालू है), आपको फ़्रेम का समय एक जैसा दिखता है और इवेंट को प्रोसेस करने में कम समय लगता है.
हमने Canary और Dev चैनलों पर इस सुविधा को चालू करके एक एक्सपेरिमेंट किया है. इससे हमें पता चला है कि हम 35% कम हिट टेस्ट करते हैं. इससे मुख्य थ्रेड ज़्यादा बार चलने के लिए तैयार हो जाता है.
वेब डेवलपर को एक अहम बात का ध्यान रखना चाहिए. वह यह है कि कोई भी अलग इवेंट (जैसे, keydown
,
keyup
,
mouseup
,
mousedown
,
touchstart
,
touchend
) होने पर, उसे तुरंत भेज दिया जाएगा. साथ ही, किसी भी इवेंट के क्रम में कोई बदलाव नहीं किया जाएगा. इस सुविधा के चालू होने पर, ज़्यादातर काम सामान्य इवेंट लूप फ़्लो में व्यवस्थित हो जाता है. इससे इनपुट इंटरवल एक जैसा रहता है. इससे, लगातार होने वाले इवेंट, scroll
और resize
इवेंट के साथ मिलते-जुलते हो जाते हैं. इन इवेंट को Chrome में इवेंट लूप फ़्लो में पहले से ही शामिल किया जा चुका है.
हमने पाया है कि ज़्यादातर ऐप्लिकेशन, ऐसे इवेंट का इस्तेमाल करते हैं जिनकी फ़्रीक्वेंसी ज़्यादा नहीं होनी चाहिए. Android ने कई सालों से इवेंट अलाइन किए हुए हैं, इसलिए इसमें कोई नई बात नहीं है. हालांकि, हो सकता है कि डेस्कटॉप प्लैटफ़ॉर्म पर साइटों को कम जानकारी वाले इवेंट मिलें. मुख्य थ्रेड में हमेशा से समस्या रही है, जिसकी वजह से इनपुट में रुकावट आती है. इसका मतलब है कि जब भी ऐप्लिकेशन काम कर रहा होगा, तो आपको पोज़िशन में उतार-चढ़ाव दिख सकते हैं. इससे यह पता लगाना मुश्किल हो जाता है कि पॉइंटर एक जगह से दूसरी जगह कैसे पहुंचा.
getCoalescedEvents()
तरीका
जैसा कि मैंने बताया, कुछ ही मामलों में ऐप्लिकेशन को पॉइंटर का पूरा पाथ जानना होता है. इसलिए, Chrome 58 में, हमने पॉइंटर इवेंट के लिए एक एक्सटेंशन लॉन्च किया है. इसका नाम getCoalescedEvents()
है. इससे, इवेंट की फ़्रीक्वेंसी में होने वाली बढ़ोतरी और गिरावट को ठीक किया जा सकता है. यहां एक उदाहरण दिया गया है, जिसमें दिखाया गया है कि इस एपीआई का इस्तेमाल करने पर, मुख्य थ्रेड पर होने वाली रुकावट को ऐप्लिकेशन से कैसे छिपाया जाता है.
किसी एक इवेंट के बजाय, उन पुराने इवेंट का कलेक्शन ऐक्सेस किया जा सकता है जिनकी वजह से वह इवेंट हुआ. Android, iOS, और Windows के नेटिव SDK टूल में एक जैसे एपीआई होते हैं. हम वेब के लिए भी एक ऐसा ही एपीआई उपलब्ध करा रहे हैं.
आम तौर पर, ड्रॉइंग ऐप्लिकेशन ने इवेंट के ऑफ़सेट को देखकर कोई पॉइंट खींचा हो सकता है:
window.addEventListener("pointermove", function(event) {
drawPoint(event.pageX, event.pageY);
});
इवेंट की कलेक्शन का इस्तेमाल करने के लिए, इस कोड को आसानी से बदला जा सकता है:
window.addEventListener("pointermove", function(event) {
var events = 'getCoalescedEvents' in event ? event.getCoalescedEvents() : [event];
for (let e of events) {
drawPoint(e.pageX, e.pageY);
}
});
ध्यान दें कि मर्ज किए गए इवेंट में हर प्रॉपर्टी अपने-आप नहीं भरती. इकट्ठा किए गए इवेंट, असल में डिस्पैच नहीं किए जाते, बल्कि सिर्फ़ ट्रैफ़िक बढ़ाने के लिए इस्तेमाल किए जाते हैं. इसलिए, इनकी हिट जांच नहीं की जाती. currentTarget
और eventPhase
जैसे कुछ फ़ील्ड में, डिफ़ॉल्ट वैल्यू दिखेंगी. डिस्पैच से जुड़े तरीकों, जैसे कि stopPropagation()
या preventDefault()
को कॉल करने से, पैरंट इवेंट पर कोई असर नहीं पड़ेगा.