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

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

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

मिलने पर

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

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

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

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

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

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

फ़ायदा पाने वाली मौजूदा रणनीतियों में समस्या है

जनरेट करने का एक सामान्य तरीका setTimeout का इस्तेमाल करता है, जिसकी टाइम आउट वैल्यू 0 है. यह इसलिए काम करता है, क्योंकि 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 को इस्तेमाल करने का तरीका क्या है—यह उन ब्राउज़र के साथ काम करता है जो इसे लागू नहीं करते हैं—यह इस पर निर्भर करता है कि आपके लक्ष्य क्या हैं. आपके पास आधिकारिक पॉलीफ़िल का इस्तेमाल करने का विकल्प है. अगर आपके मामले में ये बातें लागू होती हैं, तो पॉलीफ़िल फ़ायदेमंद साबित होता है:

  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 आपको काम का एपीआई लगता है, तो कृपया इसे बेहतर बनाने के लिए हमारी रिसर्च में हिस्सा लें. साथ ही, इसे और बेहतर बनाने के बारे में सुझाव दें.

जॉनाथन ऐलिसन की Unस्प्लैश की हीरो इमेज.