isInput Pending() के साथ बेहतर JS शेड्यूलिंग

एक नया JavaScript API, जिसकी मदद से आप लोड की परफ़ॉर्मेंस और इनपुट का जवाब देने में होने वाले उतार-चढ़ाव से बच सकते हैं.

Nate Schloss
Nate Schloss
Andrew Comminos
Andrew Comminos

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

यह समझौता न करने के लिए, Facebook ने प्रस्ताव रखा और उसे लागू किया Chromium में isInputPending() एपीआई का इस्तेमाल करें, ताकि रिस्पॉन्स देने में आसानी हो फ़ायदा मिल रहा है. ऑरिजिन ट्रायल से जुड़े सुझाव के आधार पर, हमने API का इस्तेमाल कर रहे हैं और यह बताते हुए खुशी हो रही है कि एपीआई अब Chromium में डिफ़ॉल्ट रूप से शिपिंग के तौर पर उपलब्ध होगा 87!

ब्राउज़र के साथ काम करना

ब्राउज़र सहायता

  • Chrome: 87. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • एज: 87. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • Firefox: समर्थित नहीं. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • Safari: समर्थित नहीं. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है

सोर्स

isInputPending() को Chromium पर काम करने वाले ब्राउज़र के 87 और इसके बाद के वर्शन में शिप किया गया. किसी भी दूसरे ब्राउज़र ने एपीआई को भेजने की ज़रूरत का सिग्नल नहीं दिया है.

बैकग्राउंड

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

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

जितनी बार पेज ब्राउज़र को वापस कंट्रोल करता है, उतनी बार इसमें कुछ समय लगता है ब्राउज़र अपनी इनपुट इवेंट सूची की जाँच करे, इवेंट प्रोसेस करे, और अगले JavaScript ब्लॉक. ब्राउज़र इवेंट का तेज़ी से जवाब देता है. हालांकि, पेज लोड होने में लगने वाला समय धीमा हो जाता है. अगर हम अक्सर बहुत ज़्यादा जानकारी देते हैं, बहुत धीरे लोड होता है. अगर हम कम बार नतीजे देते हैं, तो ब्राउज़र को उपयोगकर्ता इवेंट का बार-बार जवाब देते हैं और लोग निराश हो जाते हैं. मज़ेदार नहीं है.

इस डायग्राम में दिखाया गया है कि जब लंबे JS टास्क चलाए जाते हैं, तो ब्राउज़र के पास इवेंट भेजने के लिए कम समय होता है.

Facebook में, हम यह देखना चाहते थे कि अगर हम लोड करने का नया तरीका मिल गया है, जो इस झंझट को खत्म कर देगा. बुध इस बारे में Chrome पर अपने मित्रों से बात की और प्रस्ताव आया isInputPending() के लिए. isInputPending() API, इस वेब पर उपयोगकर्ता के इनपुट के लिए रुकावट डालता है और JavaScript को ब्राउज़र को दिए बिना इनपुट की जांच कर सकता है.

इस डायग्राम में दिखाया गया है कि isइनपुटPending() की मदद से आपके JS यह पता लगाता है कि क्या कोई उपयोगकर्ता इनपुट बाकी है और ब्राउज़र को एक्ज़ीक्यूशन नहीं मिला है.

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

अब हमने ऑरिजिन ट्रायल और YouTube Shopping के अन्य सदस्यों से सुझाव लिए हैं W3C वेब परफ़ॉर्मेंस वर्किंग ग्रुप और एपीआई में बदलाव लागू किए गए.

उदाहरण: एक यील्ड शेड्यूलर

मान लें कि आपके पास अपने विज्ञापनों को लोड करने के लिए कई डिसप्ले-ब्लॉकिंग काम हैं पेज का इस्तेमाल किया जा सकता है, उदाहरण के लिए, कॉम्पोनेंट से मार्कअप जनरेट करना, भाज्यों को अलग करना, या लोड होने में मदद करने वाला स्पिनर बना रहे हैं. इनमें से हर एक कैटगरी को अलग-अलग कैटगरी में बांटा जाता है काम का आइटम. शेड्यूलर पैटर्न का इस्तेमाल करके, आइए जानें कि हम इसे कैसे प्रोसेस कर सकते हैं काल्पनिक processWorkQueue() फ़ंक्शन में हमारा काम:

const DEADLINE = performance.now() + QUANTUM;
while (workQueue.length > 0) {
  if (performance.now() >= DEADLINE) {
    // Yield the event loop if we're out of time.
    setTimeout(processWorkQueue);
    return;
  }
  let job = workQueue.shift();
  job.execute();
}

बाद में, setTimeout() के ज़रिए processWorkQueue() को नए मैक्रोटास्क में शामिल करने का मतलब है कि हमने ब्राउज़र को इनपुट के लिए कुछ हद तक प्रतिक्रियाशील बने रहने की क्षमता देता है (यह काम फिर से शुरू होने से पहले इवेंट हैंडलर चलाएं). साथ ही, बाकी प्रोसेस को बाकी बिना किसी रुकावट के. हालांकि, हो सकता है कि दूसरे काम की वजह से हमारा शेड्यूल लंबे समय के लिए रद्द हो जाए जो इवेंट लूप का कंट्रोल चाहता है या अतिरिक्त QUANTUM मिलीसेकंड तक चाहता है इवेंट के इंतज़ार के समय के हिसाब से.

यह ठीक है, लेकिन क्या हम इसे बेहतर बना सकते हैं? बिल्कुल!

const DEADLINE = performance.now() + QUANTUM;
while (workQueue.length > 0) {
  if (navigator.scheduling.isInputPending() || performance.now() >= DEADLINE) {
    // Yield if we have to handle an input event, or we're out of time.
    setTimeout(processWorkQueue);
    return;
  }
  let job = workQueue.shift();
  job.execute();
}

navigator.scheduling.isInputPending() को कॉल करने पर, हम ये काम कर पाएंगे हम तुरंत जवाब देते हैं. साथ ही, यह पक्का करते हैं कि हमारा डिसप्ले ब्लॉक करने की सुविधा काम कर रही है बिना किसी रुकावट के काम करता है. अगर हमें किसी चीज़ को मैनेज करने में दिलचस्पी न हो काम पूरा होने तक, इनपुट (जैसे कि पेंटिंग) के अलावा, हम अपने हिसाब से QUANTUM की अवधि भी है.

डिफ़ॉल्ट रूप से, "लगातार" isInputPending() से इवेंट लौटाए नहीं जाते. ये mousemove, pointermove, और अन्य शामिल हैं. अगर आपकी दिलचस्पी इस बात में है कि ये भी, कोई समस्या नहीं. इसके साथ isInputPending() को एक ऑब्जेक्ट दिया गया includeContinuous को true पर सेट किया गया, हम इसे इस्तेमाल करने के लिए तैयार हैं:

const DEADLINE = performance.now() + QUANTUM;
const options = { includeContinuous: true };
while (workQueue.length > 0) {
  if (navigator.scheduling.isInputPending(options) || performance.now() >= DEADLINE) {
    // Yield if we have to handle an input event (any of them!), or we're out of time.
    setTimeout(processWorkQueue);
    return;
  }
  let job = workQueue.shift();
  job.execute();
}

हो गया! React जैसे फ़्रेमवर्क, isInputPending() की सहायता कर रहे हैं कोर शेड्यूलिंग लाइब्रेरी के लिए टारगेट करने के तरीके का इस्तेमाल किया जाता है. उम्मीद है कि जो डेवलपर isInputPending() का फ़ायदा पाने के लिए इन फ़्रेमवर्क का इस्तेमाल करते हैं वे पर्दे के पीछे की गतिविधियों में शामिल न हों और उनमें कोई अहम बदलाव न किया गया हो.

परिणाम हमेशा खराब नहीं होता

ध्यान दें कि कम नतीजे देना, हर बार काम के लिए सही समाधान नहीं होता केस. ब्राउज़र पर नियंत्रण वापस लौटाने के कई कारण हैं इनपुट इवेंट प्रोसेस करना, जैसे कि रेंडर करने और अन्य स्क्रिप्ट को एक्ज़ीक्यूट करने के लिए पेज.

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

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

हमारा सुझाव है कि आप isInputPending() का इस्तेमाल सोच-समझकर करें. अगर कोई उपयोगकर्ता को ब्लॉक करने का काम पूरा करें, उसके बाद इवेंट लूप में दूसरों से अच्छा व्यवहार करें ज़्यादा नतीजे देते हैं. लंबे टास्क नुकसान पहुंचा सकते हैं.

सुझाव/राय दें या शिकायत करें

  • अगर आपको इसे इस्तेमाल करना है, तो डेटा स्टोर करने की जगह के लिए is-input- अब तक, डेटा स्टोर करने की जगह उपलब्ध नहीं है.
  • @acomminos से संपर्क करें (खास लेखकों में से एक) Twitter पर.

नतीजा

हमें खुशी है कि isInputPending() लॉन्च हो रहा है और डेवलपर आज ही इसका इस्तेमाल करना शुरू कर दें. इस एपीआई का इस्तेमाल, Facebook ने पहली बार नया वेब एपीआई बनाया है और उसे आइडिया पर काम करने के बजाय, स्टैंडर्ड प्रस्ताव में ले जाया है शिपिंग की सुविधा उपलब्ध है. हम उन सभी लोगों को धन्यवाद देना चाहते हैं जिन्होंने इस प्लैटफ़ॉर्म तक पहुंचने में हमारी मदद की पॉइंट कर सकते हैं और Chrome पर उन सभी लोगों का खास तौर पर ज़िक्र कर सकते हैं जिन्होंने हमें बेहतर बनाने में मदद की यह आइडिया ऑफ़र कर सकते हैं और इसे शिप कर सकते हैं!

विल एच मैकमैहन की हीरो फ़ोटो अनस्प्लैश.