नेक्स्ट पेंट के इंटरैक्शन को मेज़र करना (आईएनपी)

1. परिचय

यह एक इंटरैक्टिव कोडलैब है. यह web-vitals लाइब्रेरी का इस्तेमाल करके, इंटरैक्शन टू नेक्स्ट पेंट (आईएनपी) को मेज़र करने का तरीका बताता है.

ज़रूरी शर्तें

आपको क्या सीखने को मिलेगा

  • अपने पेज पर web-vitals लाइब्रेरी जोड़ने और इसके एट्रिब्यूशन डेटा को इस्तेमाल करने का तरीका.
  • एट्रिब्यूशन डेटा का इस्तेमाल करके, आईएनपी को बेहतर बनाने की शुरुआत कहां और कैसे करें, इसका विश्लेषण करें.

आपको इन चीज़ों की ज़रूरत होगी

  • एक ऐसा कंप्यूटर जिसमें GitHub से कोड का क्लोन बनाने और npm कमांड चलाने की सुविधा है.
  • टेक्स्ट एडिटर.
  • Chrome का नया वर्शन, ताकि सभी इंटरैक्शन मेज़रमेंट काम कर सकें.

2. सेट अप करें

कोड पाएं और चलाएं

यह कोड web-vitals-codelabs डेटा स्टोर करने की जगह में मौजूद होता है.

  1. अपने टर्मिनल के रेपो का क्लोन बनाएं: git clone https://github.com/GoogleChromeLabs/web-vitals-codelabs.git.
  2. क्लोन की गई डायरेक्ट्री में जाएं: cd web-vitals-codelabs/measuring-inp.
  3. डिपेंडेंसी इंस्टॉल करें: npm ci.
  4. वेब सर्वर शुरू करें: npm run start.
  5. अपने ब्राउज़र में http://localhost:8080/ पर जाएं.

पेज आज़माएं

यह कोडलैब, आईएनपी से जुड़ी संभावित समस्याओं का पता लगाने के लिए गैस्ट्रोपॉडिकन (एक लोकप्रिय स्नेल एनाटॉमी रेफ़रंस साइट) का इस्तेमाल करता है.

गैस्ट्रोपॉडिकन डेमो पेज का स्क्रीनशॉट

पेज के साथ इंटरैक्ट करें और जानें कि कौनसे इंटरैक्शन धीमे हो रहे हैं.

3. Chrome DevTools को ढूंढना

ज़्यादा टूल में जाकर DevTools खोलें > डेवलपर टूल मेन्यू में जाकर, पेज पर राइट क्लिक करके जांच करें को चुनें या कीबोर्ड शॉर्टकट का इस्तेमाल करें.

इस कोडलैब में, हम परफ़ॉर्मेंस पैनल और कंसोल, दोनों का इस्तेमाल करेंगे. DevTools में सबसे ऊपर मौजूद टैब में, किसी भी समय इनके बीच स्विच किया जा सकता है.

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

ऐप्लिकेशन के बगल में मौजूद, DevTools परफ़ॉर्मेंस पैनल का स्क्रीनशॉट. इसमें 4x सीपीयू स्लोडाउन के विकल्प को चुना गया है

4. इंस्टॉल हो रहा है web-vitals

web-vitals एक JavaScript लाइब्रेरी है. इसकी मदद से, वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी वाली मेट्रिक का आकलन किया जाता है. इस मेट्रिक से, उपयोगकर्ताओं को मिलने वाले अनुभव का पता चलता है. लाइब्रेरी का इस्तेमाल करके उन वैल्यू को कैप्चर किया जा सकता है. इसके बाद, बाद में विश्लेषण करने के लिए उन्हें आंकड़ों के एंडपॉइंट पर बीकन किया जा सकता है, ताकि यह पता लगाया जा सके कि धीमे इंटरैक्शन कब और कहां हो रहे हैं.

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

यह कोडलैब, एनपीएम से इंस्टॉल होगा और स्क्रिप्ट को सीधे लोड करेगा, ताकि किसी खास बिल्ड प्रोसेस में जाने से बचा जा सके.

web-vitals के दो वर्शन हैं, जिनका इस्तेमाल किया जा सकता है:

  • "मानक" बिल्ड का इस्तेमाल तब किया जाना चाहिए, जब आपको किसी पेज लोड होने पर Core Web Vitals से जुड़ी मेट्रिक वैल्यू को ट्रैक करना हो.
  • "एट्रिब्यूशन" बिल्ड हर मेट्रिक में अतिरिक्त डीबग जानकारी जोड़ता है, ताकि यह पता लगाया जा सके कि कोई मेट्रिक क्यों सही वैल्यू पर खत्म होती है.

इस कोडलैब में आईएनपी को मापने के लिए, हमें एट्रिब्यूशन बिल्ड चाहिए.

npm install -D web-vitals चलाकर, web-vitals को प्रोजेक्ट के devDependencies में जोड़ें

web-vitals को पेज पर जोड़ें:

स्क्रिप्ट के एट्रिब्यूशन वर्शन को index.html के निचले हिस्से में जोड़ें और नतीजों को कंसोल में लॉग करें:

<script type="module">
  import {onINP} from './node_modules/web-vitals/dist/web-vitals.attribution.js';

  onINP(console.log);
</script>

इसे आज़माएं

कंसोल खोलकर पेज के साथ फिर से इंटरैक्ट करने की कोशिश करें. पेज पर क्लिक करने से, कुछ भी लॉग नहीं किया जाता!

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

web-vitals, ज़्यादा जानकारी वाली रिपोर्ट के लिए reportAllChanges विकल्प देता है. इस सुविधा के चालू होने पर, हर इंटरैक्शन को रिपोर्ट नहीं किया जाता. हालांकि, जब भी कोई इंटरैक्शन पहले वाले किसी इंटरैक्शन से धीमा होता है, तो उसे रिपोर्ट किया जाता है.

स्क्रिप्ट में विकल्प जोड़कर और पेज के साथ फिर से इंटरैक्ट करके देखें:

<script type="module">
  import {onINP} from './node_modules/web-vitals/dist/web-vitals.attribution.js';

  onINP(console.log, {reportAllChanges: true});
</script>

पेज को रीफ़्रेश करने के बाद, इंटरैक्शन की रिपोर्ट कंसोल को भेज दी जाती है. ऐसा तब होता है, जब कोई नया सिस्टम सबसे धीमा होता है. उदाहरण के लिए, खोज बॉक्स में टाइप करें और फिर इनपुट को मिटाएं.

DevTools कंसोल का स्क्रीनशॉट, जिसमें आईएनपी मैसेज प्रिंट किए गए हैं

5. एट्रिब्यूशन में क्या होता है?

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

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

(डेमो) कुकी स्वीकार करने के लिए, हां पर क्लिक करें. इसके बाद, DevTools कंसोल में लॉग किए गए आईएनपी डेटा को देखें.

DevTools कंसोल में आईएनपी डेटा ऑब्जेक्ट को लॉग किया गया

यह टॉप लेवल जानकारी स्टैंडर्ड और एट्रिब्यूशन वेब-वाइटल बिल्ड, दोनों में उपलब्ध है:

{
  name: 'INP',
  value: 344,
  rating: 'needs-improvement',
  entries: [...],
  id: 'v4-1715732159298-8028729544485',
  navigationType: 'reload',
  attribution: {...},
}

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

हालांकि, इस दौरान क्या हो रहा है, यह जानने के लिए हमारी सबसे ज़्यादा दिलचस्पी attribution प्रॉपर्टी में है. एट्रिब्यूशन डेटा बनाने के लिए, web-vitals पता लगाता है कि कौनसा लॉन्ग ऐनिमेशन फ़्रेम (LoAF), क्लिक इवेंट के साथ ओवरलैप करता है. इसके बाद, एलओएफ़ उस फ़्रेम के दौरान बिताए गए समय के बारे में ज़्यादा जानकारी दे सकता है. इसमें, चलने वाली स्क्रिप्ट से लेकर requestAnimationFrame कॉलबैक, स्टाइल, और लेआउट में बिताए गए समय तक की जानकारी शामिल होती है.

ज़्यादा जानकारी देखने के लिए, attribution प्रॉपर्टी को बड़ा करें. डेटा में ज़्यादा जानकारी शामिल होती है.

attribution: {
  interactionTargetElement: Element,
  interactionTarget: '#confirm',
  interactionType: 'pointer',

  inputDelay: 27,
  processingDuration: 295.6,
  presentationDelay: 21.4,

  processedEventEntries: [...],
  longAnimationFrameEntries: [...],
}

सबसे पहले, यह जानकारी है कि किन चीज़ों से इंटरैक्ट किया गया:

  • interactionTargetElement: उस एलिमेंट का लाइव रेफ़रंस जिससे इंटरैक्ट किया गया था. ऐसा तब होता है, जब एलिमेंट को डीओएम से नहीं हटाया गया हो.
  • interactionTarget: यह पेज में एलिमेंट को ढूंढने का विकल्प है.

इसके बाद, समय को अच्छे तरीके से बांटा गया है:

  • inputDelay: उपयोगकर्ता के इंटरैक्शन शुरू करने (उदाहरण के लिए, माउस पर क्लिक करने) और उस इंटरैक्शन के लिए इवेंट लिसनर के चलने के बीच का समय. इस मामले में, इनपुट में देरी सिर्फ़ 27 मिलीसेकंड थी. भले ही, सीपीयू थ्रॉटलिंग चालू हो.
  • processingDuration: इवेंट लिसनर को इवेंट पूरा होने में लगने वाला समय. अक्सर, किसी एक इवेंट के लिए पेज के एक से ज़्यादा लिसनर होंगे (उदाहरण के लिए, pointerdown, pointerup, और click). अगर वे सभी एक ही ऐनिमेशन फ़्रेम में चलते हैं, तो उन्हें इस बार जोड़ दिया जाएगा. इस मामले में, प्रोसेस करने में लगने वाला समय 295.6 मिलीसेकंड लगता है—जो आईएनपी समय का बड़ा हिस्सा है.
  • presentationDelay: इवेंट लिसनर के इवेंट लिसनर के पूरा होने से लेकर, ब्राउज़र के अगले फ़्रेम को पेंट करने तक का समय. इस मामले में, 21.4 मिलीसेकंड.

यह पता लगाने के लिए कि किन चीज़ों को ऑप्टिमाइज़ करना है, आईएनपी के ये चरण अहम सिग्नल हो सकते हैं. Optimize INP की गाइड में, इस विषय के बारे में ज़्यादा जानकारी मौजूद है.

processedEventEntries में थोड़ा और गहराई से जाने पर, इसमें पांच इवेंट शामिल होते हैं. ये इवेंट, टॉप-लेवल आईएनपी entries कलेक्शन में शामिल नहीं हैं. इन दोनों में क्या अंतर है?

processedEventEntries: [
  {
    name: 'mouseover',
    entryType: 'event',
    startTime: 1801.6,
    duration: 344,
    processingStart: 1825.3,
    processingEnd: 1825.3,
    cancelable: true
  },
  {
    name: 'mousedown',
    entryType: 'event',
    startTime: 1801.6,
    duration: 344,
    processingStart: 1825.3,
    processingEnd: 1825.3,
    cancelable: true
  },
  {name: 'mousedown', ...},
  {name: 'mouseup', ...},
  {name: 'click', ...},
],

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

आखिर में, longAnimationFrameEntries कलेक्शन मौजूद है. यह एक एंट्री हो सकती है. हालांकि, कुछ मामलों में इंटरैक्शन कई फ़्रेम में हो सकता है. यहां एक लंबे ऐनिमेशन फ़्रेम का सबसे आसान मामला दिया गया है.

longAnimationFrameEntries

एलओएएफ़ एंट्री को बड़ा करना:

longAnimationFrameEntries: [{
  name: 'long-animation-frame',
  startTime: 1823,
  duration: 319,

  renderStart: 2139.5,
  styleAndLayoutStart: 2139.7,
  firstUIEventTimestamp: 1801.6,
  blockingDuration: 268,

  scripts: [{...}]
}],

इसमें कई काम की वैल्यू होती हैं, जैसे कि स्टाइलिंग में लगने वाले समय को बांटना. लंबी ऐनिमेशन फ़्रेम एपीआई के लेख में इन प्रॉपर्टी के बारे में ज़्यादा जानकारी दी गई है. फ़िलहाल, हमारी दिलचस्पी scripts प्रॉपर्टी में है. इस प्रॉपर्टी में, लंबे समय तक चलने वाले फ़्रेम के लिए ज़िम्मेदार स्क्रिप्ट के बारे में जानकारी देने वाली एंट्री होती हैं:

scripts: [{
  name: 'script',
  invoker: 'BUTTON#confirm.onclick',
  invokerType: 'event-listener',

  startTime: 1828.6,
  executionStart: 1828.6,
  duration: 294,

  sourceURL: 'http://localhost:8080/third-party/cmp.js',
  sourceFunctionName: '',
  sourceCharPosition: 1144
}]

इस मामले में, हम यह बता सकते हैं कि समय मुख्य रूप से एक event-listener में बिताया गया था, जिसे BUTTON#confirm.onclick को शुरू किया गया था. हम स्क्रिप्ट सोर्स का यूआरएल और उस वर्ण की पोज़िशन भी देख सकते हैं जहां फ़ंक्शन को तय किया गया था!

खाना पैक कराकर ले जाने की सुविधा

इस एट्रिब्यूशन डेटा से, इस मामले का पता कैसे लगाया जा सकता है?

  • इंटरैक्शन, button#confirm एलिमेंट (attribution.interactionTarget और स्क्रिप्ट एट्रिब्यूशन एंट्री की invoker प्रॉपर्टी) पर हुए क्लिक से ट्रिगर हुआ.
  • मुख्य तौर पर, इवेंट लिसनर को एक्ज़ीक्यूट करने में समय बिताया गया (कुल मेट्रिक value की तुलना में attribution.processingDuration से).
  • धीमा इवेंट लिसनर कोड, third-party/cmp.js (scripts.sourceURL से) में तय किए गए क्लिक लिसनर से शुरू होता है.

यह जानने के लिए कि हमें कहां ऑप्टिमाइज़ करना होगा, यह काफ़ी डेटा है!

6. कई इवेंट लिसनर

पेज को रीफ़्रेश करें, ताकि DevTools कंसोल साफ़ दिख सके और कुकी के लिए सहमति वाला इंटरैक्शन, सबसे लंबा इंटरैक्शन न हो.

खोज बॉक्स में टाइप करना शुरू करें. एट्रिब्यूशन डेटा क्या दिखाता है? आपके हिसाब से क्या चल रहा है?

एट्रिब्यूशन डेटा

सबसे पहले, डेमो की जांच करने के एक उदाहरण का हाई लेवल स्कैन:

{
  name: 'INP',
  value: 1072,
  rating: 'poor',
  attribution: {
    interactionTargetElement: Element,
    interactionTarget: '#search-terms',
    interactionType: 'keyboard',

    inputDelay: 3.3,
    processingDuration: 1060.6,
    presentationDelay: 8.1,

    processedEventEntries: [...],
    longAnimationFrameEntries: [...],
  }
}

यह input#search-terms एलिमेंट वाले कीबोर्ड इंटरैक्शन से खराब आईएनपी वैल्यू है. इसमें सीपीयू थ्रॉटलिंग की सुविधा चालू है. ज़्यादातर समय—1072 मिलीसेकंड तक कुल आईएनपी में से 1061 मिलीसेकंड—प्रोसेसिंग में लगे.

हालांकि, scripts की एंट्री ज़्यादा दिलचस्प हैं.

लेआउट थ्रैशिंग

scripts कलेक्शन की पहली एंट्री से हमें कुछ अहम जानकारी मिलती है:

scripts: [{
  name: 'script',
  invoker: 'BUTTON#confirm.onclick',
  invokerType: 'event-listener',

  startTime: 4875.6,
  executionStart: 4875.6,
  duration: 497,
  forcedStyleAndLayoutDuration: 388,

  sourceURL: 'http://localhost:8080/js/index.js',
  sourceFunctionName: 'handleSearch',
  sourceCharPosition: 940
},
...]

प्रोसेस होने का ज़्यादातर समय, स्क्रिप्ट के इस एक्ज़ीक्यूशन के दौरान होता है. यह एक input लिसनर है (इनवॉइस करने वाला INPUT#search-terms.oninput होता है). फ़ंक्शन का नाम (handleSearch) दिया गया है, जैसे कि index.js सोर्स फ़ाइल में वर्ण की पोज़िशन.

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

इसे ठीक करने की सबसे पहली प्राथमिकता होनी चाहिए.

बार-बार सुनने वाले लोग

अलग-अलग, अगली दो स्क्रिप्ट एंट्री के बारे में कुछ भी खास नहीं है:

scripts: [...,
{
  name: 'script',
  invoker: '#document.onkeyup',
  invokerType: 'event-listener',

  startTime: 5375.3,
  executionStart: 5375.3,
  duration: 124,

  sourceURL: 'http://localhost:8080/js/index.js',
  sourceFunctionName: '',
  sourceCharPosition: 1526,
},
{
  name: 'script',
  invoker: '#document.onkeyup',
  invokerType: 'event-listener',

  startTime: 5673.9,
  executionStart: 5673.9,
  duration: 95,

  sourceURL: 'http://localhost:8080/js/index.js',
  sourceFunctionName: '',
  sourceCharPosition: 1526
}]

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

इसमें अजीब बात यह है कि दोनों एक ही सोर्स फ़ाइल और वर्ण की स्थिति से हैं.

ब्राउज़र ने एक ही ऐनिमेशन फ़्रेम में कई कीप्रेस को प्रोसेस कर दिया. इससे, कोई भी चीज़ पेंट करने से पहले, यह इवेंट लिसनर दो बार चला गया!

इस इफ़ेक्ट की वजह से कई चीज़ें बढ़ सकती हैं. किसी इवेंट को सुनने में लोगों को जितने ज़्यादा समय लगता है, उतने ही ज़्यादा इनपुट इवेंट आ सकते हैं. इससे इंटरैक्शन की धीमी रफ़्तार को बढ़ाया जा सकता है.

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

7. इनपुट में देरी

मुख्य थ्रेड के व्यस्त होने की वजह से इनपुट में देरी होती है. उपयोगकर्ता के इंटरैक्ट करने और इवेंट लिसनर के इंटरैक्शन की प्रोसेस शुरू करने में लगने वाले समय की वजह से ऐसा होता है. इसकी कई वजहें हो सकती हैं:

  • पेज लोड हो रहा है और मुख्य थ्रेड, डीओएम सेट अप करने, पेज को लेआउट, और स्टाइल के साथ-साथ स्क्रिप्ट का आकलन करने और उन्हें चलाने के शुरुआती काम में व्यस्त है.
  • आम तौर पर, पेज व्यस्त होता है. उदाहरण के लिए, कंप्यूटेशन का काम, स्क्रिप्ट पर आधारित ऐनिमेशन या विज्ञापन.
  • पिछले इंटरैक्शन को प्रोसेस होने में इतना समय लगता है कि उनकी वजह से, ऐसे इंटरैक्शन में देरी हो जाती है जो पिछले उदाहरण में देखे गए थे.

डेमो पेज में एक सीक्रेट सुविधा है, जहां पेज के सबसे ऊपर मौजूद घोंघा लोगो पर क्लिक करने पर, वह ऐनिमेट होना शुरू हो जाता है और मुख्य थ्रेड वाली JavaScript पर काम करने लगता है.

  • ऐनिमेशन शुरू करने के लिए घोंघे के लोगो पर क्लिक करें.
  • JavaScript टास्क तब ट्रिगर होते हैं, जब घोंघा, बाउंस के निचले हिस्से में होता है. पेज के साथ बाउंस के निचले हिस्से के जितना हो सके उतना इंटरैक्ट करने की कोशिश करें और देखें कि आईएनपी की कितनी ऊंचाई को ट्रिगर किया जा सकता है.

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

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

यहां पर एक उदाहरण एट्रिब्यूशन दिया गया है, जो स्नेल बाउंस के दौरान केवल खोज बॉक्स पर फ़ोकस करने से जुड़ा है:

{
  name: 'INP',
  value: 728,
  rating: 'poor',

  attribution: {
    interactionTargetElement: Element,
    interactionTarget: '#search-terms',
    interactionType: 'pointer',

    inputDelay: 702.3,
    processingDuration: 4.9,
    presentationDelay: 20.8,

    longAnimationFrameEntries: [{
      name: 'long-animation-frame',
      startTime: 2064.8,
      duration: 790,

      renderStart: 2065,
      styleAndLayoutStart: 2854.2,
      firstUIEventTimestamp: 0,
      blockingDuration: 740,

      scripts: [{...}]
    }]
  }
}

जैसा कि अनुमान था, इवेंट लिसनर तेज़ी से एक्ज़ीक्यूट करते हैं. यह प्रोसेसिंग कुल 4.9 मिलीसेकंड दिखाती है. खराब इंटरैक्शन का ज़्यादातर हिस्सा, इनपुट में देरी के लिए खर्च होता है. इस वजह से, कुल 728 में से 702.3 मिलीसेकंड लगे.

इस स्थिति को डीबग करना मुश्किल हो सकता है. भले ही हम जानते हैं कि उपयोगकर्ता ने किस चीज़ से इंटरैक्ट किया था और कैसे, लेकिन हम यह भी जानते हैं कि वह हिस्सा तुरंत पूरा हो गया और वह कोई समस्या नहीं थी. इसके बजाय, पेज पर कुछ और थी, जिसकी वजह से इंटरैक्शन शुरू होने में देर हो गई. हालांकि, हमें कैसे पता चलेगा कि उसे कहां से ढूंढना शुरू करना है?

LoAF स्क्रिप्ट प्रविष्टियाँ दिन बचाने के लिए उपलब्ध हैं:

scripts: [{
  name: 'script',
  invoker: 'SPAN.onanimationiteration',
  invokerType: 'event-listener',

  startTime: 2065,
  executionStart: 2065,
  duration: 788,

  sourceURL: 'http://localhost:8080/js/index.js',
  sourceFunctionName: 'cryptodaphneCoinHandler',
  sourceCharPosition: 1831
}]

हालांकि, इस फ़ंक्शन का इंटरैक्शन से कोई लेना-देना नहीं था, लेकिन इसने ऐनिमेशन फ़्रेम को धीमा कर दिया. इस वजह से, इंटरैक्शन इवेंट के साथ जुड़े LoAF डेटा में इसे शामिल किया जाता है.

इससे हम देख सकते हैं कि इंटरैक्शन प्रोसेसिंग में देरी करने वाला फ़ंक्शन किस तरह (animationiteration लिसनर की मदद से) ट्रिगर हुआ, असल में कौनसा फ़ंक्शन ज़िम्मेदार था, और वह हमारी सोर्स फ़ाइलों में कहां मौजूद था.

8. प्रज़ेंटेशन में देरी: जब कोई अपडेट पेंट ही नहीं हो रहा

प्रज़ेंटेशन में देरी का मतलब है कि इवेंट लिसनर के चलने के बाद, ब्राउज़र एक नया फ़्रेम पेंट करने के बाद ही उपयोगकर्ता को सुझाव दिखाता है.

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

यह कैसा दिखता है?

{
  name: 'INP',
  value: 376,
  rating: 'needs-improvement',
  delta: 352,

  attribution: {
    interactionTarget: '#sidenav-button>svg',
    interactionType: 'pointer',

    inputDelay: 12.8,
    processingDuration: 14.7,
    presentationDelay: 348.5,

    longAnimationFrameEntries: [{
      name: 'long-animation-frame',
      startTime: 651,
      duration: 365,

      renderStart: 673.2,
      styleAndLayoutStart: 1004.3,
      firstUIEventTimestamp: 138.6,
      blockingDuration: 315,

      scripts: [{...}]
    }]
  }
}

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

scripts: [{
  entryType: 'script',
  invoker: 'FrameRequestCallback',
  invokerType: 'user-callback',

  startTime: 673.8,
  executionStart: 673.8,
  duration: 330,

  sourceURL: 'http://localhost:8080/js/side-nav.js',
  sourceFunctionName: '',
  sourceCharPosition: 1193,
}]

scripts कलेक्शन में एक एंट्री देखने पर, हमें पता चलता है कि FrameRequestCallback से, user-callback में कितना समय बीता है. इस बार, requestAnimationFrame कॉलबैक की वजह से, प्रज़ेंटेशन में देरी हो रही है.

9. नतीजा

फ़ील्ड का डेटा इकट्ठा करना

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

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

इसके बजाय, आपको अपने खास ऐप्लिकेशन के बारे में सोचना होगा. इससे यह तय होगा कि कौनसा ऐप्लिकेशन सबसे ज़्यादा काम का है और डेटा को इकट्ठा करने का तरीका क्या है. उदाहरण के लिए, एट्रिब्यूशन डेटा को वापस लाने से पहले, web-vitals सिलेक्टर को अपने आइडेंटिफ़ायर से बदला जा सकता है. ऐसा टारगेट जिस कॉम्पोनेंट में है या टारगेट को पूरा करने वाली ARIA रोल के आधार पर होता है.

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

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

एट्रिब्यूशन हर जगह!

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

अब आप किसी भी साइट पर आईएनपी एट्रिब्यूशन डेटा का इस्तेमाल करने के लिए तैयार हैं!

अगर आपके पास किसी पेज में बदलाव करने का ऐक्सेस नहीं है, तब भी इस कोडलैब से इस प्रोसेस को फिर से बनाया जा सकता है. ऐसा करने के लिए, DevTools कंसोल में नीचे दिए गए स्निपेट को चलाएं और देखें कि आपको क्या मिल सकता है:

const script = document.createElement('script');
script.src = 'https://unpkg.com/web-vitals@4/dist/web-vitals.attribution.iife.js';
script.onload = function () {
  webVitals.onINP(console.log, {reportAllChanges: true});
};
document.head.appendChild(script);

ज़्यादा जानें