फ़ील्ड में धीमे इंटरैक्शन का पता लगाना

अपनी वेबसाइट के फ़ील्ड डेटा में धीमे इंटरैक्शन ढूंढने का तरीका जानें, ताकि आपको पेज के रिस्पॉन्स में लगने वाले समय को बेहतर बनाने के अवसर मिल सकें.

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

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

अपनी वेबसाइट के आईएनपी का आकलन करने के लिए, CrUX का इस्तेमाल करना

अगर आपकी वेबसाइट के उपयोगकर्ताओं से फ़ील्ड डेटा इकट्ठा नहीं किया जा रहा है, तो CrUX एक अच्छा विकल्प हो सकता है. CrUX, Chrome के उन असल उपयोगकर्ताओं से फ़ील्ड डेटा इकट्ठा करता है जिन्होंने टेलीमेट्री डेटा भेजने का विकल्प चुना है.

CrUX डेटा कई अलग-अलग जगहों पर दिखता है. यह इस बात पर निर्भर करता है कि आपको किस तरह की जानकारी चाहिए. CrUX, आईएनपी और अन्य Core Web Vitals के लिए डेटा उपलब्ध करा सकता है:

  • PageSpeed Insights का इस्तेमाल करके, अलग-अलग पेजों और पूरे ऑरिजिन की परफ़ॉर्मेंस की जानकारी.
  • पेज के टाइप. उदाहरण के लिए, कई ई-कॉमर्स वेबसाइटों पर प्रॉडक्ट की जानकारी वाले पेज और प्रॉडक्ट लिस्टिंग वाले पेज होते हैं. Search Console में, यूनीक पेज टाइप के लिए CrUX डेटा देखा जा सकता है.

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

PageSpeed Insights में CrUX से दिखाया गया फ़ील्ड डेटा. इसमें Core Web Vitals के तौर पर एलसीपी, आईएनपी, और सीएलएस को दिखाया गया है. साथ ही, गड़बड़ी की जानकारी देने वाली मेट्रिक के तौर पर टीटीएफ़बी और एफ़सीपी को दिखाया गया है. इसके अलावा, Core Web Vitals मेट्रिक के तौर पर एफ़आईडी को दिखाया गया है, जो अब काम नहीं करती.
PageSpeed Insights में दिखने वाले CrUX डेटा का रीडआउट. इस उदाहरण में, दिए गए वेब पेज के आईएनपी को बेहतर बनाने की ज़रूरत है.

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

web-vitals JavaScript लाइब्रेरी की मदद से फ़ील्ड डेटा इकट्ठा करना

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

Browser Support

  • Chrome: 96.
  • Edge: 96.
  • Firefox: 144.
  • Safari: 26.2.

Source

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

import {onINP} from 'web-vitals';

onINP(({name, value, rating}) => {
  console.log(name);    // 'INP'
  console.log(value);   // 512
  console.log(rating);  // 'poor'
});

अपने उपयोगकर्ताओं से मिले फ़ील्ड डेटा का विश्लेषण करने के लिए, आपको यह डेटा कहीं भेजना होगा:

import {onINP} from 'web-vitals';

onINP(({name, value, rating}) => {
  // Prepare JSON to be sent for collection. Note that
  // you can add anything else you'd want to collect here:
  const body = JSON.stringify({name, value, rating});

  // Use `sendBeacon` to send data to an analytics endpoint.
  // For Google Analytics, see https://github.com/GoogleChrome/web-vitals#send-the-results-to-google-analytics.
  navigator.sendBeacon('/analytics', body);
});

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

web-vitals लाइब्रेरी के एट्रिब्यूशन बिल्ड की मदद से, ज़्यादा जानकारी पाना

web-vitals लाइब्रेरी का एट्रिब्यूशन बिल्ड, अतिरिक्त डेटा दिखाता है. यह डेटा, फ़ील्ड में मौजूद उपयोगकर्ताओं से मिल सकता है. इससे आपको वेबसाइट के आईएनपी पर असर डालने वाले इंटरैक्शन से जुड़ी समस्याओं को बेहतर तरीके से हल करने में मदद मिलती है. इस डेटा को लाइब्रेरी के onINP() तरीके में दिखाए गए attribution ऑब्जेक्ट की मदद से ऐक्सेस किया जा सकता है:

import {onINP} from 'web-vitals/attribution';

onINP(({name, value, rating, attribution}) => {
  console.log(name);         // 'INP'
  console.log(value);        // 56
  console.log(rating);       // 'good'
  console.log(attribution);  // Attribution data object
});
web-vitals लाइब्रेरी से कंसोल लॉग कैसे दिखते हैं. इस उदाहरण में कंसोल, मेट्रिक का नाम (आईएनपी), आईएनपी वैल्यू (56), आईएनपी थ्रेशोल्ड (अच्छा) के अंदर मौजूद वैल्यू, और एट्रिब्यूशन ऑब्जेक्ट में दिखाई गई अलग-अलग जानकारी दिखाता है. इसमें Long Animation Frames API की एंट्री भी शामिल हैं.
कंसोल में, वेब-वाइटल लाइब्रेरी का डेटा कैसे दिखता है.

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

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

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

attribution ऑब्जेक्ट कुंजी डेटा
interactionTarget पेज की आईएनपी वैल्यू जनरेट करने वाले एलिमेंट पर ले जाने वाला सीएसएस सिलेक्टर. उदाहरण के लिए, button#save.
interactionType इंटरैक्शन का टाइप, जैसे कि क्लिक, टैप या कीबोर्ड इनपुट.
inputDelay* इंटरैक्शन के इनपुट में होने वाली देरी.
processingDuration* उपयोगकर्ता के इंटरैक्शन के जवाब में, पहले इवेंट लिसनर के चलने से लेकर सभी इवेंट लिसनर की प्रोसेसिंग पूरी होने तक का समय.
presentationDelay* इंटरैक्शन का प्रज़ेंटेशन डिले. यह इवेंट हैंडलर के खत्म होने से लेकर, अगले फ़्रेम के दिखने तक का समय होता है.
longAnimationFrameEntries* इंटरैक्शन से जुड़े LoAF की एंट्री. ज़्यादा जानकारी के लिए, अगला सेक्शन देखें.
*वर्शन 4 में नया

web-vitals लाइब्रेरी के वर्शन 4 से, आपको समस्या वाले इंटरैक्शन के बारे में ज़्यादा अहम जानकारी मिल सकती है. इसके लिए, आपको आईएनपी फ़ेज़ ब्रेकडाउन (इनपुट में लगने वाला समय, प्रोसेसिंग में लगने वाला समय, और प्रज़ेंटेशन में लगने वाला समय) और लॉन्ग ऐनिमेशन फ़्रेम एपीआई (LoAF) से मिलने वाले डेटा का इस्तेमाल करना होगा.

Long Animation Frames API (LoAF)

Browser Support

  • Chrome: 123.
  • Edge: 123.
  • Firefox: not supported.
  • Safari: not supported.

Source

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

web-vitals लाइब्रेरी का एट्रिब्यूशन बिल्ड, attribution ऑब्जेक्ट की longAnimationFrameEntries कुंजी के तहत LoAF एंट्री का कलेक्शन दिखाता है. नीचे दी गई टेबल में, डेटा के कुछ ऐसे मुख्य हिस्से दिए गए हैं जो हर LoAF एंट्री में मिल सकते हैं:

LoAF एंट्री ऑब्जेक्ट कुंजी डेटा
duration लंबे ऐनिमेशन फ़्रेम की अवधि, लेआउट के पूरा होने तक. हालांकि, इसमें पेंटिंग और कंपोज़िटिंग शामिल नहीं है.
blockingDuration फ़्रेम में मौजूद वह कुल समय जिसमें ज़्यादा समय लेने वाले टास्क की वजह से, ब्राउज़र तुरंत जवाब नहीं दे पाया. इस ब्लॉकिंग टाइम में, JavaScript चलाने वाले ज़्यादा समय लेने वाले टास्क के साथ-साथ, फ़्रेम में रेंडर होने वाले ज़्यादा समय लेने वाले टास्क भी शामिल हो सकते हैं.
firstUIEventTimestamp फ़्रेम के दौरान, इवेंट को सूची में शामिल किए जाने का टाइमस्टैंप. इससे इंटरैक्शन के इनपुट में लगने वाले समय की शुरुआत का पता लगाने में मदद मिलती है.
startTime फ़्रेम के शुरू होने का टाइमस्टैंप.
renderStart फ़्रेम को रेंडर करने का काम कब शुरू हुआ. इसमें कोई भी requestAnimationFrame कॉलबैक (और अगर लागू हो, तो ResizeObserver कॉलबैक) शामिल है. हालांकि, यह स्टाइल/लेआउट का कोई भी काम शुरू होने से पहले हो सकता है.
styleAndLayoutStart जब फ़्रेम में स्टाइल/लेआउट का काम होता है. इससे, अन्य उपलब्ध टाइमस्टैंप को ध्यान में रखते हुए, स्टाइल/लेआउट के काम की अवधि का पता लगाया जा सकता है.
scripts आइटम का एक कलेक्शन, जिसमें स्क्रिप्ट एट्रिब्यूशन की जानकारी शामिल होती है. इससे पेज के आईएनपी में योगदान मिलता है.
LoAF मॉडल के हिसाब से, लंबे ऐनिमेशन फ़्रेम का विज़ुअलाइज़ेशन.
LoAF API के मुताबिक, लंबे ऐनिमेशन फ़्रेम के समय का डायग्राम (blockingDuration को छोड़कर).

इस जानकारी से आपको यह समझने में मदद मिल सकती है कि इंटरैक्शन धीमा क्यों है. हालांकि, LoAF एंट्री से मिलने वाले scripts कलेक्शन पर खास तौर पर ध्यान देना चाहिए:

स्क्रिप्ट एट्रिब्यूशन ऑब्जेक्ट की कुंजी डेटा
invoker इनवोकर. यह अगली लाइन में बताए गए, इन्वोकर टाइप के आधार पर अलग-अलग हो सकता है. इनवोकर के उदाहरणों में 'IMG#id.onload', 'Window.requestAnimationFrame' या 'Response.json.then' जैसी वैल्यू शामिल हो सकती हैं.
invokerType इनवोकर का टाइप. इसकी वैल्यू 'user-callback', 'event-listener', 'resolve-promise', 'reject-promise', 'classic-script' या 'module-script' हो सकती है.
sourceURL उस स्क्रिप्ट का यूआरएल जहां से लंबा ऐनिमेशन फ़्रेम शुरू हुआ.
sourceCharPosition sourceURL से पहचानी गई स्क्रिप्ट में वर्ण की पोज़िशन.
sourceFunctionName पहचानी गई स्क्रिप्ट में मौजूद फ़ंक्शन का नाम.

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

धीमे इंटरैक्शन की सामान्य वजहों का पता लगाना और उन्हें मेज़र करना

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

प्रोसेस होने में ज़्यादा समय लगना

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

import {onINP} from 'web-vitals/attribution';

onINP(({name, value, attribution}) => {
  const {processingDuration} = attribution; // 512.5
});

यह सोचना स्वाभाविक है कि इंटरैक्शन धीमा होने की मुख्य वजह यह है कि आपके इवेंट हैंडलर कोड को चलने में बहुत ज़्यादा समय लगा. हालांकि, ऐसा हमेशा नहीं होता! इस बात की पुष्टि करने के बाद कि समस्या यही है, LoAF डेटा की मदद से ज़्यादा जानकारी हासिल की जा सकती है:

import {onINP} from 'web-vitals/attribution';

onINP(({name, value, attribution}) => {
  const {processingDuration} = attribution; // 512.5

  // Get the longest script from LoAF covering `processingDuration`:
  const loaf = attribution.longAnimationFrameEntries.at(-1);
  const script = loaf?.scripts.toSorted((a, b) => b.duration - a.duration)[0];

  if (script) {
    // Get attribution for the long-running event handler:
    const {invokerType} = script;        // 'event-listener'
    const {invoker} = script;            // 'BUTTON#update.onclick'
    const {sourceURL} = script;          // 'https://example.com/app.js'
    const {sourceCharPosition} = script; // 83
    const {sourceFunctionName} = script; // 'update'
  }
});

ऊपर दिए गए कोड स्निपेट में देखा जा सकता है कि LoAF डेटा का इस्तेमाल करके, इंटरैक्शन के लिए प्रोसेसिंग में लगने वाले समय की ज़्यादा वैल्यू की सटीक वजह का पता लगाया जा सकता है. इसमें ये शामिल हैं:

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

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

इनपुट में ज़्यादा देरी होना

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

import {onINP} from 'web-vitals/attribution';

onINP(({name, value, attribution}) => {
  const {inputDelay} = attribution; // 125.59439536
});

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

क्या यह पेज लोड होने के दौरान हुआ?

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

import {onINP} from 'web-vitals/attribution';

onINP(({name, value, attribution}) => {
  const {inputDelay} = attribution; // 125.59439536

  // Get the longest script from the first LoAF entry:
  const loaf = attribution.longAnimationFrameEntries[0];
  const script = loaf?.scripts.toSorted((a, b) => b.duration - a.duration)[0];

  if (script) {
    // Invoker types can describe if script eval blocked the main thread:
    const {invokerType} = script;    // 'classic-script' | 'module-script'
    const {sourceLocation} = script; // 'https://example.com/app.js'
  }
});

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

क्या यह पेज लोड होने के बाद हुआ?

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

import {onINP} from 'web-vitals/attribution';

onINP(({name, value, attribution}) => {
  const {inputDelay} = attribution; // 125.59439536

  // Get the longest script from the first LoAF entry:
  const loaf = attribution.longAnimationFrameEntries[0];
  const script = loaf?.scripts.toSorted((a, b) => b.duration - a.duration)[0];

  if (script) {
    const {invokerType} = script;        // 'user-callback'
    const {sourceURL} = script;          // 'https://example.com/app.js'
    const {sourceCharPosition} = script; // 83
    const {sourceFunctionName} = script; // 'update'
  }
});

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

  • 'user-callback' से पता चलता है कि ब्लॉक करने वाला टास्क setInterval, setTimeout या requestAnimationFrame से था.
  • 'event-listener' से पता चलता है कि ब्लॉक करने वाला टास्क, पहले के किसी इनपुट से जुड़ा था. वह इनपुट, सूची में था और अब भी प्रोसेस हो रहा है.
  • 'resolve-promise' और 'reject-promise' का मतलब है कि ब्लॉक करने वाला टास्क, पहले शुरू किए गए किसी एसिंक्रोनस काम की वजह से था. साथ ही, इसे उस समय हल या अस्वीकार किया गया, जब उपयोगकर्ता ने पेज से इंटरैक्ट करने की कोशिश की. इस वजह से, इंटरैक्शन में देरी हुई.

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

प्रज़ेंटेशन में ज़्यादा देरी होना

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

import {onINP} from 'web-vitals/attribution';

onINP(({name, value, attribution}) => {
  const {presentationDelay} = attribution; // 113.32307691
});

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

स्टाइल और लेआउट से जुड़े काम में ज़्यादा समय लगना

प्रज़ेंटेशन में ज़्यादा देरी होने की वजह, स्टाइल को फिर से कैलकुलेट करने और लेआउट में बदलाव करने में लगने वाला ज़्यादा समय हो सकता है. ऐसा कई वजहों से हो सकता है. जैसे, जटिल सीएसएस सिलेक्टर और बड़े साइज़ के डीओएम. web-vitals लाइब्रेरी में दिखने वाले LoAF के समय की मदद से, इस काम में लगने वाले समय को मेज़र किया जा सकता है:

import {onINP} from 'web-vitals/attribution';

onINP(({name, value, attribution}) => {
  const {presentationDelay} = attribution; // 113.32307691

  // Get the longest script from the last LoAF entry:
  const loaf = attribution.longAnimationFrameEntries.at(-1);
  const script = loaf?.scripts.toSorted((a, b) => b.duration - a.duration)[0];

  // Get necessary timings:
  const {startTime} = loaf; // 2120.5
  const {duration} = loaf;  // 1002

  // Figure out the ending timestamp of the frame (approximate):
  const endTime = startTime + duration; // 3122.5

  // Get the start timestamp of the frame's style/layout work:
  const {styleAndLayoutStart} = loaf; // 3011.17692309

  // Calculate the total style/layout duration:
  const styleLayoutDuration = endTime - styleAndLayoutStart; // 111.32307691

  if (script) {
    // Get attribution for the event handler that triggered
    // the long-running style and layout operation:
    const {invokerType} = script;        // 'event-listener'
    const {invoker} = script;            // 'BUTTON#update.onclick'
    const {sourceURL} = script;          // 'https://example.com/app.js'
    const {sourceCharPosition} = script; // 83
    const {sourceFunctionName} = script; // 'update'
  }
});

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

लंबे समय तक चलने वाले requestAnimationFrame कॉलबैक

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

अगर इन कॉलबैक में किया गया काम मुश्किल है, तो इन्हें पूरा होने में काफ़ी समय लग सकता है. अगर आपको लगता है कि प्रज़ेंटेशन में ज़्यादा देरी की वजह requestAnimationFrame के साथ किया जा रहा काम है, तो इन स्थितियों की पहचान करने के लिए, web-vitals लाइब्रेरी से मिले LoAF डेटा का इस्तेमाल किया जा सकता है:

onINP(({name, value, attribution}) => {
  const {presentationDelay} = attribution; // 543.1999999880791

  // Get the longest script from the last LoAF entry:
  const loaf = attribution.longAnimationFrameEntries.at(-1);
  const script = loaf?.scripts.toSorted((a, b) => b.duration - a.duration)[0];

  // Get the render start time and when style and layout began:
  const {renderStart} = loaf;         // 2489
  const {styleAndLayoutStart} = loaf; // 2989.5999999940395

  // Calculate the `requestAnimationFrame` callback's duration:
  const rafDuration = styleAndLayoutStart - renderStart; // 500.59999999403954

  if (script) {
    // Get attribution for the event handler that triggered
    // the long-running requestAnimationFrame callback:
    const {invokerType} = script;        // 'user-callback'
    const {invoker} = script;            // 'FrameRequestCallback'
    const {sourceURL} = script;          // 'https://example.com/app.js'
    const {sourceCharPosition} = script; // 83
    const {sourceFunctionName} = script; // 'update'
  }
});

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

नतीजा

फ़ील्ड डेटा, जानकारी का सबसे अच्छा सोर्स है. इससे यह समझने में मदद मिलती है कि असल उपयोगकर्ताओं को फ़ील्ड में किन इंटरैक्शन से समस्या हो रही है. वेब-वाइटल JavaScript लाइब्रेरी (या आरयूएम सेवा देने वाली कंपनी) जैसे फ़ील्ड डेटा कलेक्शन टूल का इस्तेमाल करके, आपको यह पता चल सकता है कि किन इंटरैक्शन में सबसे ज़्यादा समस्याएं आ रही हैं. इसके बाद, लैब में समस्या वाले इंटरैक्शन को फिर से जनरेट करके उन्हें ठीक किया जा सकता है.