शेड्यूलr.yield ऑरिजिन ट्रायल पेश है

ऐसी वेबसाइटें बनाना जो उपयोगकर्ता के इनपुट का तुरंत जवाब देती हों, वेब की परफ़ॉर्मेंस के सबसे चुनौतीपूर्ण पहलुओं में से एक है. Chrome की टीम, वेब डेवलपर की मदद करने के लिए इस पर लगातार काम कर रही है. इसी साल, यह एलान किया गया था कि इंटरैक्शन टू नेक्स्ट पेंट (आईएनपी) मेट्रिक को एक्सपेरिमेंट से बदलकर, 'मंज़ूरी बाकी है' स्टेटस में बदल दिया जाएगा. अब यह मार्च 2024 में, वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी देने वाली मेट्रिक के तौर पर पेज पर मौजूद लिंक को क्लिक करके उस पर पहुंचने वाला समय (एफ़आईडी) की जगह ले लेगी.

Chrome की टीम लगातार नए एपीआई उपलब्ध करा रही है, ताकि वेब डेवलपर अपनी वेबसाइटों को ज़्यादा से ज़्यादा तेज़ बना सकें. फ़िलहाल, Chrome की टीम scheduler.yield के लिए ऑरिजिन ट्रायल चला रही है. यह ट्रायल, Chrome के 115 वर्शन से शुरू हुआ है. scheduler.yield, शेड्यूलर एपीआई में जोड़ा गया एक नया पैरामीटर है. इसकी मदद से, मुख्य थ्रेड को कंट्रोल करने का तरीका आम तौर पर इस्तेमाल किए जाने वाले तरीकों के मुकाबले आसान और बेहतर होता है.

मिलने पर

JavaScript, टास्क को पूरा करने के लिए 'पूरी तरह से चलाने के बाद ही बंद होना' मॉडल का इस्तेमाल करता है. इसका मतलब है कि जब कोई टास्क मुख्य थ्रेड पर चलता है, तो वह टास्क पूरा होने तक चलता रहता है. किसी टास्क के पूरा होने पर, कंट्रोल मुख्य थ्रेड को yield कर दिया जाता है. इससे मुख्य थ्रेड, सूची में मौजूद अगले टास्क को प्रोसेस कर पाता है.

ऐसे मामलों को छोड़कर जब कोई टास्क पूरा नहीं होता, जैसे कि कभी न खत्म होने वाला लूप. उदाहरण के लिए, यील्डिंग JavaScript के टास्क शेड्यूलिंग लॉजिक का एक ज़रूरी पहलू है. यह होगा, बस यह तय करना है कि कब होगा. जल्द से जल्द ऐसा करना बेहतर होता है. जब किसी टास्क को पूरा होने में ज़्यादा समय लगता है यानी वह 50 मिलीसेकंड से ज़्यादा का हो, तो उसे लंबे टास्क माना जाता है.

लंबे टास्क, पेज के रिस्पॉन्स में देरी का एक बड़ा कारण हैं. ऐसा इसलिए होता है, क्योंकि इनसे ब्राउज़र को उपयोगकर्ता के इनपुट का जवाब देने में देरी होती है. लंबे टास्क जितनी ज़्यादा बार और ज़्यादा देर तक चलते हैं, उपयोगकर्ताओं को यह लगने की संभावना उतनी ही ज़्यादा होती है कि पेज पर काम करने में ज़्यादा समय लग रहा है या पेज काम नहीं कर रहा है.

हालांकि, अगर आपका कोड ब्राउज़र में कोई टास्क शुरू करता है, तो इसका मतलब यह नहीं है कि आपको मुख्य थ्रेड को फिर से कंट्रोल करने से पहले, उस टास्क के पूरा होने का इंतज़ार करना होगा. किसी टास्क को साफ़ तौर पर दिखाकर, किसी पेज पर उपयोगकर्ता के इनपुट का रिस्पॉन्स बेहतर बनाया जा सकता है. इससे टास्क, अगले उपलब्ध अवसर में खत्म होने के लिए तैयार हो जाता है. इससे, अन्य टास्क को मुख्य थ्रेड पर जल्दी समय मिल जाता है. ऐसा तब नहीं होता, जब उन्हें लंबे टास्क के पूरा होने का इंतज़ार करना पड़ता है.

इस इलस्ट्रेशन में दिखाया गया है कि किसी टास्क को अलग-अलग हिस्सों में बांटने से, इनपुट के लिए रिस्पॉन्स मिलने में कम समय लगता है. सबसे ऊपर, लंबा टास्क किसी इवेंट हैंडलर को तब तक ब्लॉक करता है, जब तक टास्क पूरा नहीं हो जाता. सबसे नीचे, छोटे-छोटे हिस्सों में बांटा गया टास्क, इवेंट हैंडलर को तय समय से पहले चलाने की अनुमति देता है.
मुख्य थ्रेड को फिर से कंट्रोल देने का विज़ुअलाइज़ेशन. सबसे ऊपर, किसी टास्क के पूरा होने के बाद ही जनरेट होता है. इसका मतलब है कि कंट्रोल को मुख्य थ्रेड पर वापस लाने से पहले, टास्क को पूरा होने में ज़्यादा समय लग सकता है. सबसे नीचे, साफ़ तौर पर, किसी लंबे टास्क को कई छोटे टास्क में बांटकर, टास्क पूरा किया जाता है. इससे उपयोगकर्ता के इंटरैक्शन जल्द चलते हैं, जिससे इनपुट का जवाब देने में लगने वाला समय और आईएनपी बेहतर होता है.

साफ़ तौर पर येल करने का मतलब है कि ब्राउज़र को यह बताना कि "मुझे पता है कि मुझे जो काम करना है उसमें कुछ समय लग सकता है. इसलिए, मुझे नहीं चाहिए कि उपयोगकर्ता के इनपुट या अन्य ज़रूरी कामों का जवाब देने से पहले, आपको पूरा काम करना पड़े". यह डेवलपर के टूलबॉक्स में मौजूद एक अहम टूल है. इससे उपयोगकर्ता अनुभव को बेहतर बनाने में काफ़ी मदद मिलती है.

मौजूदा यील्डिंग की रणनीतियों से जुड़ी समस्या

0 के टाइम आउट की वैल्यू के साथ setTimeout का इस्तेमाल करके, नतीजे पाने का एक सामान्य तरीका. यह इसलिए काम करता है, क्योंकि setTimeout को पास किया गया कॉलबैक, बचे हुए काम को अलग टास्क में ले जाता है. इस टास्क को आगे चलने के लिए सूची में रखा जाता है. ब्राउज़र के अपने-आप काम करने का इंतज़ार करने के बजाय, "चलो इस बड़े काम को छोटे-छोटे हिस्सों में बांट दें" कहा जा रहा है.

हालांकि, setTimeout का इस्तेमाल करके टास्क को पूरा करने पर, एक अनचाहा असर पड़ सकता है: टास्क पूरा होने के बाद मिलने वाला काम, टास्क की सूची में सबसे पीछे चला जाएगा. उपयोगकर्ता इंटरैक्शन के ज़रिए शेड्यूल किए गए टास्क, अब भी पहले की तरह सूची में रहेंगे. हालांकि, जो काम आप सही तरीके से करने के बाद करना चाहते हैं वह दूसरे टास्क की वजह से देरी से हो सकता है. इसकी वजह यह है कि प्रतिस्पर्धा करने वाले सोर्स से जो टास्क पहले शेड्यूल किए गए थे उनकी वजह से ज़्यादा देर हो सकती है.

इसे इस्तेमाल करने का तरीका जानने के लिए, Glitch का यह डेमो देखें या यहां एम्बेड किए गए वर्शन को आज़माएं. डेमो में कुछ बटन होते हैं जिन पर क्लिक किया जा सकता है. साथ ही, उनके नीचे एक बॉक्स होता है, जिसमें टास्क के चलने की जानकारी लॉग होती है. पेज पर पहुंचने के बाद, ये कार्रवाइयां करें:

  1. सबसे ऊपर मौजूद, टास्क समय-समय पर चलाएं लेबल वाले बटन पर क्लिक करें. इससे, ब्लॉक करने वाले टास्क समय-समय पर चलने के लिए शेड्यूल हो जाएंगे. इस बटन पर क्लिक करने पर, टास्क लॉग में कई मैसेज दिखेंगे. इनमें setInterval की मदद से ब्लॉकिंग टास्क चलाया गया लिखा होगा.
  2. इसके बाद, लूप चलाएं, हर बार 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 को काम करते देखने के लिए, ये काम करें:

  1. chrome://flags पर नेविगेट करें.
  2. वेब प्लैटफ़ॉर्म की एक्सपेरिमेंटल सुविधाएं एक्सपेरिमेंट चालू करें. ऐसा करने के बाद, आपको Chrome को रीस्टार्ट करना पड़ सकता है.
  3. डेमो पेज पर जाएं या इस सूची के नीचे दिए गए, एम्बेड किए गए वर्शन का इस्तेमाल करें.
  4. सबसे ऊपर मौजूद, टास्क समय-समय पर चलाएं लेबल वाले बटन पर क्लिक करें.
  5. आखिर में, लूप चलाएं, हर बार 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 वर्शन से, इसे दो तरीकों से आज़माया जा सकता है:

  1. अगर आपको अपने डिवाइस पर scheduler.yield का इस्तेमाल करना है, तो Chrome के पता बार में chrome://flags टाइप करें और डालें. इसके बाद, प्रयोग के तौर पर उपलब्ध वेब प्लैटफ़ॉर्म की सुविधाएं सेक्शन में मौजूद ड्रॉपडाउन से चालू करें चुनें. इससे scheduler.yield (और नई सुविधाएं) सिर्फ़ आपके Chrome इंस्टेंस में उपलब्ध होंगी.
  2. अगर आपको सार्वजनिक तौर पर ऐक्सेस किए जा सकने वाले ऑरिजिन के लिए, scheduler.yield को असली Chromium उपयोगकर्ताओं के लिए चालू करना है, तो आपको scheduler.yield ऑरिजिन ट्रायल के लिए साइन अप करना होगा. इससे, किसी तय समय के लिए सुझाई गई सुविधाओं को सुरक्षित तरीके से आज़माया जा सकता है. साथ ही, Chrome की टीम को यह अहम जानकारी मिलती है कि फ़ील्ड में उन सुविधाओं का इस्तेमाल कैसे किया जाता है. ऑरिजिन ट्रायल के काम करने के तरीके के बारे में ज़्यादा जानने के लिए, यह गाइड पढ़ें.

scheduler.yield का इस्तेमाल कैसे किया जाए, यह इस बात पर निर्भर करता है कि आपके लक्ष्य क्या हैं. यह भी ज़रूरी है कि आपके ब्राउज़र में scheduler.yield की सुविधा काम करती हो. आधिकारिक पॉलीफ़िल का इस्तेमाल किया जा सकता है. पॉलीफ़िल तब काम आता है, जब आपकी स्थिति इनमें से किसी एक में हो:

  1. आपके ऐप्लिकेशन में, टास्क शेड्यूल करने के लिए पहले से ही scheduler.postTask का इस्तेमाल किया जा रहा है.
  2. आपको टास्क और फ़सल की प्राथमिकताएं सेट करनी हों.
  3. 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 से ली गई हीरो इमेज, जिसे जोनाथन एलिसन ने बनाया है.