ऐसी वेबसाइटें बनाना जो उपयोगकर्ता के इनपुट का तुरंत जवाब देती हों, वेब की परफ़ॉर्मेंस के सबसे चुनौतीपूर्ण पहलुओं में से एक है. Chrome की टीम, वेब डेवलपर की मदद करने के लिए इस पर लगातार काम कर रही है. इस साल ही, इंटरैक्शन टू नेक्स्ट पेंट (आईएनपी) मेट्रिक को एक्सपेरिमेंट के तौर पर इस्तेमाल करने की सुविधा से हटाकर, 'मंज़ूरी बाकी है' स्टेटस पर ले जाने का एलान किया गया था. अब यह मार्च 2024 में, वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी देने वाली मेट्रिक के तौर पर पेज पर मौजूद लिंक को क्लिक करके उस पर पहुंचने वाला समय (एफ़आईडी) की जगह ले लेगी.
Chrome की टीम लगातार नए एपीआई उपलब्ध करा रही है, ताकि वेब डेवलपर अपनी वेबसाइटों को ज़्यादा से ज़्यादा तेज़ बना सकें. फ़िलहाल, Chrome की टीम scheduler.yield
के लिए ऑरिजिन ट्रायल चला रही है. यह ट्रायल, Chrome के 115 वर्शन से शुरू हुआ है. scheduler.yield
, शेड्यूलर एपीआई में जोड़ा गया एक नया पैरामीटर है. इसकी मदद से, आम तौर पर इस्तेमाल किए जाने वाले तरीकों के मुकाबले, मुख्य थ्रेड को आसानी से और बेहतर तरीके से कंट्रोल किया जा सकता है.
फ़सल कटने पर
JavaScript, टास्क को पूरा करने के लिए 'पूरी तरह से चलाने के बाद ही रुकना' मॉडल का इस्तेमाल करता है. इसका मतलब है कि जब कोई टास्क मुख्य थ्रेड पर चलता है, तो वह टास्क पूरा होने तक चलता रहता है. किसी टास्क के पूरा होने पर, कंट्रोल मुख्य थ्रेड को yield कर दिया जाता है. इससे मुख्य थ्रेड, सूची में मौजूद अगले टास्क को प्रोसेस कर पाता है.
कुछ मामलों में, टास्क कभी पूरा नहीं होता. जैसे, इनफ़ाइनाइट लूप. ऐसे मामलों को छोड़कर, JavaScript के टास्क शेड्यूलिंग लॉजिक में, 'नतीजा देना' एक ज़रूरी हिस्सा है. यह होगा, बस यह तय करना है कि कब होगा. जल्द से जल्द ऐसा करना बेहतर होता है. जब टास्क पूरे होने में बहुत ज़्यादा समय लगता है, जैसे कि 50 मिलीसेकंड से ज़्यादा, तो उन्हें लंबे टास्क माना जाता है.
लंबे टास्क, पेज के रिस्पॉन्स में देरी का एक मुख्य कारण हैं. ऐसा इसलिए होता है, क्योंकि इनसे ब्राउज़र को उपयोगकर्ता के इनपुट का जवाब देने में देरी होती है. लंबे टास्क जितनी ज़्यादा बार और ज़्यादा देर तक चलते हैं, उपयोगकर्ताओं को यह लगने की संभावना उतनी ही ज़्यादा होती है कि पेज पर काम करने में ज़्यादा समय लग रहा है या पेज काम नहीं कर रहा है.
हालांकि, अगर आपका कोड ब्राउज़र में कोई टास्क शुरू करता है, तो इसका मतलब यह नहीं है कि आपको मुख्य थ्रेड को फिर से कंट्रोल करने से पहले, उस टास्क के पूरा होने का इंतज़ार करना होगा. किसी टास्क में साफ़ तौर पर 'yield' का इस्तेमाल करके, किसी पेज पर उपयोगकर्ता के इनपुट के रिस्पॉन्स में लगने वाले समय को कम किया जा सकता है. इससे टास्क को छोटे-छोटे हिस्सों में बांट दिया जाता है, ताकि अगली बार उपलब्ध होने पर उसे पूरा किया जा सके. इससे, अन्य टास्क को मुख्य थ्रेड पर जल्दी समय मिल जाता है. ऐसा तब नहीं होता, जब उन्हें लंबे टास्क के पूरा होने का इंतज़ार करना पड़ता है.
साफ़ तौर पर येल करने का मतलब है कि ब्राउज़र को यह बताना कि "मुझे पता है कि मुझे जो काम करना है उसमें कुछ समय लग सकता है. इसलिए, मुझे नहीं चाहिए कि उपयोगकर्ता के इनपुट या अन्य ज़रूरी कामों का जवाब देने से पहले, आपको पूरा काम करना पड़े". यह डेवलपर के टूलबॉक्स में मौजूद एक अहम टूल है. इससे उपयोगकर्ता अनुभव को बेहतर बनाने में काफ़ी मदद मिलती है.
मौजूदा यील्डिंग की रणनीतियों से जुड़ी समस्या
0
के टाइम आउट की वैल्यू के साथ setTimeout
का इस्तेमाल करके, आम तौर पर नतीजे पाने का तरीका. ऐसा इसलिए होता है, क्योंकि setTimeout
को पास किया गया कॉलबैक, बाकी बचे काम को एक अलग टास्क में ले जाएगा. इस टास्क को बाद में लागू करने के लिए, सूची में जोड़ दिया जाएगा. ब्राउज़र के अपने-आप काम करने का इंतज़ार करने के बजाय, "चलो इस बड़े काम को छोटे-छोटे हिस्सों में बांटते हैं".
हालांकि, setTimeout
का इस्तेमाल करके टास्क को पूरा करने पर, एक अनचाहा असर पड़ सकता है: टास्क पूरा होने के बाद आने वाला काम, टास्क की सूची में सबसे पीछे चला जाएगा. उपयोगकर्ता के इंटरैक्शन के हिसाब से शेड्यूल किए गए टास्क, पहले की तरह ही सूची में सबसे ऊपर दिखेंगे. हालांकि, साफ़ तौर पर 'वीडियो बंद करें' बोलने के बाद, बाकी बचे काम में देरी हो सकती है. ऐसा, उससे पहले शेड्यूल किए गए दूसरे टास्क की वजह से होगा.
इसे इस्तेमाल करने का तरीका जानने के लिए, Glitch का यह डेमो देखें या नीचे एम्बेड किए गए वर्शन को आज़माएं. डेमो में कुछ बटन होते हैं जिन पर क्लिक किया जा सकता है. साथ ही, उनके नीचे एक बॉक्स होता है, जिसमें टास्क के चलने की जानकारी लॉग होती है. पेज पर पहुंचने के बाद, ये कार्रवाइयां करें:
- सबसे ऊपर मौजूद, टास्क समय-समय पर चलाएं लेबल वाले बटन पर क्लिक करें. इससे, ब्लॉक करने वाले टास्क समय-समय पर चलने के लिए शेड्यूल हो जाएंगे. इस बटन पर क्लिक करने पर, टास्क लॉग में कई मैसेज दिखेंगे. इनमें
setInterval
की मदद से ब्लॉकिंग टास्क चलाया गया लिखा होगा. - इसके बाद, लूप चलाएं, हर बार
setTimeout
के साथ नतीजा दें लेबल वाले बटन पर क्लिक करें.
आपको डेमो के सबसे नीचे मौजूद बॉक्स में कुछ ऐसा दिखेगा:
Processing loop item 1
Processing loop item 2
Ran blocking task via setInterval
Processing loop item 3
Ran blocking task via setInterval
Processing loop item 4
Ran blocking task via setInterval
Processing loop item 5
Ran blocking task via setInterval
Ran blocking task via setInterval
इस आउटपुट में, "टास्क की सूची खत्म होने" का व्यवहार दिखाया गया है. यह व्यवहार, setTimeout
के साथ 'नतीजा दें' फ़ंक्शन का इस्तेमाल करने पर होता है. यह लूप पांच आइटम प्रोसेस करता है. हर आइटम को प्रोसेस करने के बाद, setTimeout
दिखाता है.
यह वेब पर होने वाली एक सामान्य समस्या को दिखाता है: किसी स्क्रिप्ट के लिए, खास तौर पर तीसरे पक्ष की स्क्रिप्ट के लिए, ऐसा कोई टेंपर फ़ंक्शन रजिस्टर करना असामान्य नहीं है जो किसी इंटरवल पर काम करता है. setTimeout
के साथ 'टास्क की सूची खत्म होने पर' व्यवहार का मतलब है कि टास्क के अन्य सोर्स से मिलने वाला काम, लूप के 'खत्म होने पर' मिलने वाले काम से पहले सूची में शामिल हो सकता है.
आपके ऐप्लिकेशन के हिसाब से, यह एक अच्छा नतीजा हो सकता है या नहीं. हालांकि, ज़्यादातर मामलों में, इस व्यवहार की वजह से डेवलपर आसानी से मुख्य थ्रेड का कंट्रोल नहीं छोड़ पाते. येल्ड करना अच्छा होता है, क्योंकि इससे उपयोगकर्ता इंटरैक्शन जल्दी चल पाते हैं. हालांकि, इससे मुख्य थ्रेड पर, उपयोगकर्ता इंटरैक्शन के अलावा दूसरे कामों को भी समय मिल पाता है. यह एक असली समस्या है—लेकिन scheduler.yield
इसे हल करने में मदद कर सकता है!
scheduler.yield
में जाएं
scheduler.yield
, Chrome के 115 वर्शन से वेब प्लैटफ़ॉर्म की एक्सपेरिमेंटल सुविधा के तौर पर, फ़्लैग के पीछे उपलब्ध है. आपके मन में यह सवाल आ सकता है कि "जब setTimeout
पहले से ही नतीजे दिखाता है, तो मुझे नतीजे पाने के लिए किसी खास फ़ंक्शन की ज़रूरत क्यों है?"
ध्यान दें कि setTimeout
को डिज़ाइन करते समय, फ़ंक्शन को 'वीयल्ड करें' मोड में चलाने का मकसद नहीं था. हालांकि, आने वाले समय में किसी खास समय पर कॉलबैक चलाने के लिए, उसे शेड्यूल करने पर यह एक अच्छा साइड इफ़ेक्ट होता है. भले ही, 0
की टाइम आउट वैल्यू तय की गई हो. हालांकि, यह याद रखना ज़्यादा ज़रूरी है कि setTimeout
का इस्तेमाल करके, टास्क की सूची में बचे हुए काम को पीछे भेजा जाता है. डिफ़ॉल्ट रूप से, scheduler.yield
बाकी बचे काम को सूची में सबसे आगे भेजता है. इसका मतलब है कि जिस काम को 'बाहर निकलें' सुविधा का इस्तेमाल करने के बाद तुरंत फिर से शुरू करना है वह अन्य सोर्स से मिलने वाले टास्क के पीछे नहीं रहेगा. हालांकि, उपयोगकर्ता के इंटरैक्शन को छोड़कर.
scheduler.yield
एक ऐसा फ़ंक्शन है जो मुख्य थ्रेड को नतीजा देता है और कॉल किए जाने पर Promise
दिखाता है. इसका मतलब है कि इसे async
फ़ंक्शन में await
किया जा सकता है:
async function yieldy () {
// Do some work...
// ...
// Yield!
await scheduler.yield();
// Do some more work...
// ...
}
scheduler.yield
को काम करते हुए देखने के लिए, यह तरीका अपनाएं:
chrome://flags
पर नेविगेट करें.- वेब प्लैटफ़ॉर्म की एक्सपेरिमेंटल सुविधाएं एक्सपेरिमेंट चालू करें. ऐसा करने के बाद, आपको Chrome को रीस्टार्ट करना पड़ सकता है.
- डेमो पेज पर जाएं या इस सूची के नीचे दिए गए, एम्बेड किए गए वर्शन का इस्तेमाल करें.
- सबसे ऊपर मौजूद, टास्क समय-समय पर चलाएं लेबल वाले बटन पर क्लिक करें.
- आखिर में, लूप चलाएं, हर बार
scheduler.yield
के साथ नतीजा दें लेबल वाले बटन पर क्लिक करें.
पेज के सबसे नीचे मौजूद बॉक्स में आउटपुट कुछ ऐसा दिखेगा:
Processing loop item 1
Processing loop item 2
Processing loop item 3
Processing loop item 4
Processing loop item 5
Ran blocking task via setInterval
Ran blocking task via setInterval
Ran blocking task via setInterval
Ran blocking task via setInterval
Ran blocking task via setInterval
setTimeout
का इस्तेमाल करके डेमो दिखाने के बजाय, यह देखा जा सकता है कि लूप हर बार दोहराए जाने के बाद भी, बाकी काम को सूची में सबसे पीछे नहीं भेजता, बल्कि सबसे आगे भेजता है. इससे आपको दोनों कामों में फ़ायदा मिलता है: अपनी वेबसाइट पर इनपुट रिस्पॉन्सिवनेस को बेहतर बनाने के लिए, आपके पास 'वीटो' करने का विकल्प होता है. साथ ही, यह भी पक्का किया जा सकता है कि 'वीटो' करने के बाद, आपको जो काम करना है उसमें देरी न हो.
इसे आज़माएं!
अगर आपको scheduler.yield
पसंद आया है और आपको इसे आज़माना है, तो Chrome के 115 वर्शन से, इसे दो तरीकों से आज़माया जा सकता है:
- अगर आपको
scheduler.yield
को स्थानीय तौर पर आज़माना है, तो Chrome के पता बार मेंchrome://flags
टाइप करें और Enter दबाएं. इसके बाद, वेब प्लैटफ़ॉर्म की एक्सपेरिमेंटल सुविधाएं सेक्शन में ड्रॉपडाउन से चालू करें को चुनें. इससेscheduler.yield
(और नई सुविधाएं) सिर्फ़ आपके Chrome इंस्टेंस में उपलब्ध होंगी. - अगर आपको सार्वजनिक तौर पर ऐक्सेस किए जा सकने वाले ऑरिजिन पर, Chromium के असली उपयोगकर्ताओं के लिए
scheduler.yield
को चालू करना है, तो आपकोscheduler.yield
के ऑरिजिन ट्रायल के लिए साइन अप करना होगा. इससे, किसी तय समय के लिए सुझाई गई सुविधाओं को सुरक्षित तरीके से आज़माया जा सकता है. साथ ही, Chrome की टीम को यह अहम जानकारी मिलती है कि फ़ील्ड में उन सुविधाओं का इस्तेमाल कैसे किया जाता है. ऑरिजिन ट्रायल के काम करने के तरीके के बारे में ज़्यादा जानने के लिए, यह गाइड पढ़ें.
scheduler.yield
का इस्तेमाल कैसे किया जाए, यह इस बात पर निर्भर करता है कि आपके लक्ष्य क्या हैं. यह भी ज़रूरी है कि आपके ब्राउज़र में scheduler.yield
की सुविधा काम करती हो. आधिकारिक पॉलीफ़िल का इस्तेमाल किया जा सकता है. पॉलीफ़िल तब काम आता है, जब आपकी स्थिति में ये बातें लागू हों:
- आपके ऐप्लिकेशन में, टास्क शेड्यूल करने के लिए पहले से ही
scheduler.postTask
का इस्तेमाल किया जा रहा है. - आपको टास्क और फ़सल की प्राथमिकताएं सेट करनी हों.
- आपको
scheduler.postTask
एपीआई कीTaskController
क्लास की मदद से, टास्क रद्द करने या उनकी प्राथमिकता बदलने की सुविधा चाहिए.
अगर इससे आपकी स्थिति के बारे में जानकारी नहीं मिलती है, तो हो सकता है कि पॉलीफ़िल आपके लिए सही न हो. ऐसे में, अपने फ़ॉलबैक को कई तरीकों से रोल आउट किया जा सकता है. पहला तरीका, scheduler.yield
का इस्तेमाल तब करता है, जब वह उपलब्ध हो. हालांकि, अगर वह उपलब्ध नहीं है, तो setTimeout
का इस्तेमाल किया जाता है:
// A function for shimming scheduler.yield and setTimeout:
function yieldToMain () {
// Use scheduler.yield if it exists:
if ('scheduler' in window && 'yield' in scheduler) {
return scheduler.yield();
}
// Fall back to setTimeout:
return new Promise(resolve => {
setTimeout(resolve, 0);
});
}
// Example usage:
async function doWork () {
// Do some work:
// ...
await yieldToMain();
// Do some other work:
// ...
}
यह काम कर सकता है, लेकिन जैसा कि आप अनुमान लगा सकते हैं कि scheduler.yield
के साथ काम न करने वाले ब्राउज़र, "लाइन में सबसे आगे" व्यवहार के बिना नतीजे देंगे. अगर इसका मतलब है कि आपको कोई भी नतीजा नहीं चाहिए, तो कोई दूसरा तरीका आज़माएं. यह तरीका scheduler.yield
का इस्तेमाल करता है, बशर्ते वह उपलब्ध हो. अगर वह उपलब्ध नहीं है, तो कोई नतीजा नहीं मिलेगा:
// A function for shimming scheduler.yield with no fallback:
function yieldToMain () {
// Use scheduler.yield if it exists:
if ('scheduler' in window && 'yield' in scheduler) {
return scheduler.yield();
}
// Fall back to nothing:
return;
}
// Example usage:
async function doWork () {
// Do some work:
// ...
await yieldToMain();
// Do some other work:
// ...
}
scheduler.yield
, शेड्यूलर एपीआई में एक दिलचस्प सुविधा है. उम्मीद है कि इससे डेवलपर, मौजूदा रणनीतियों के मुकाबले, रिस्पॉन्सिवनेस को बेहतर बना पाएंगे. अगर आपको scheduler.yield
एक काम का एपीआई लगता है, तो कृपया इसे बेहतर बनाने के लिए हमारी रिसर्च में हिस्सा लें. साथ ही, इस बारे में सुझाव/राय दें कि इसे और कैसे बेहतर बनाया जा सकता है.
Unsplash से ली गई हीरो इमेज, जिसे जोनाथन एलिसन ने बनाया है.