शेड्यूल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 टाइप करें और Enter दबाएं. इसके बाद, वेब प्लैटफ़ॉर्म की एक्सपेरिमेंटल सुविधाएं सेक्शन में ड्रॉपडाउन से चालू करें को चुनें. ऐसा करने पर, scheduler.yield (और नई सुविधाएं) सिर्फ़ आपके Chrome इंस्टेंस में उपलब्ध होंगी.
  2. अगर आपको सार्वजनिक तौर पर ऐक्सेस किए जा सकने वाले ऑरिजिन पर, Chromium के असली उपयोगकर्ताओं के लिए scheduler.yield को चालू करना है, तो आपको 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 का इस्तेमाल करता है. हालांकि, अगर 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 से ली गई हीरो इमेज, जिसे जोनाथन एलिसन ने बनाया है.