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

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

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

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

अपनी वेबसाइट के INP का आकलन करने के लिए, CrUX से शुरुआत करें

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

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

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

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

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

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

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

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

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

  • Chrome: 96.
  • एज: 96.
  • Firefox: समर्थित नहीं.
  • Safari: यह सुविधा काम नहीं करती.

सोर्स

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

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 के अलावा ज़्यादा कुछ नहीं बता सकता. ऐसी स्थिति में ही वेब-वाइटल लाइब्रेरी के एट्रिब्यूशन बिल्ड का काम होता है.

वेब-विटल्स लाइब्रेरी के एट्रिब्यूशन बिल्ड के साथ आगे बढ़ें

वेब-विटल्स लाइब्रेरी का एट्रिब्यूशन बिल्ड, ज़्यादा डेटा दिखाता है. यह डेटा, फ़ील्ड में मौजूद उपयोगकर्ताओं से मिल सकता है. इससे, आपको अपनी वेबसाइट के आईएनपी पर असर डालने वाले समस्या वाले इंटरैक्शन को बेहतर तरीके से हल करने में मदद मिलती है. इस डेटा को लाइब्रेरी के 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
});
वेब-विटल्स लाइब्रेरी के कंसोल लॉग कैसे दिखते हैं. इस उदाहरण में दिया गया कंसोल, मेट्रिक (आईएनपी) का नाम और आईएनपी वैल्यू (56) दिखाता है. इसमें यह वैल्यू आईएनपी थ्रेशोल्ड (अच्छी) के अंदर रहती है. साथ ही, एट्रिब्यूशन ऑब्जेक्ट में दिखाई गई अलग-अलग जानकारी के अलग-अलग बिट भी दिखते हैं. इसमें, लंबे ऐनिमेशन फ़्रेम एपीआई से मिली एंट्री भी शामिल हैं.
वेब-वाइटल लाइब्रेरी का डेटा, कंसोल में कैसा दिखता है.

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

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

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

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

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

Long Animation Frames API (LoAF)

ब्राउज़र के इस्तेमाल से जुड़ी सहायता

  • Chrome: 123.
  • Edge: 123.
  • Firefox: यह सुविधा काम नहीं करती.
  • Safari: यह सुविधा काम नहीं करती.

सोर्स

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

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

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

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

स्क्रिप्ट एट्रिब्यूशन ऑब्जेक्ट की कुंजी Data
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 डेटा का इस्तेमाल कैसे किया जा सकता है, ताकि धीमे इंटरैक्शन की वजहों का पता लगाया जा सके.

प्रोसेस होने की लंबी अवधि

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

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.sort((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.sort((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.sort((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' का मतलब है कि ब्लॉक करने वाला टास्क, किसी ऐसे काम से जुड़ा था जिसे पहले शुरू किया गया था और जिसे तब हल या अस्वीकार किया गया था, जब उपयोगकर्ता ने पेज से इंटरैक्ट करने की कोशिश की थी. इससे इंटरैक्शन में देरी हुई.

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

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

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

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

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

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

महंगे स्टाइल और लेआउट का काम

प्रज़ेंटेशन में देरी होने की कई वजहें हो सकती हैं. जैसे, स्टाइल की फिर से गिनती और लेआउट से जुड़ा काम. ये काम कई वजहों से हो सकते हैं. जैसे, जटिल सीएसएस सेलेक्टर और बड़े DOM साइज़. वेब-विटल लाइब्रेरी में दिखने वाले 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.sort((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 के साथ किए जा रहे काम की वजह से है, तो इन स्थितियों की पहचान करने के लिए, वेब-विटल्स लाइब्रेरी से मिले 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.sort((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 कॉलबैक में बीत रहा है, तो पक्का करें कि इन कॉलबैक में सिर्फ़ वही काम किया जा रहा हो जिससे यूज़र इंटरफ़ेस में असल अपडेट हो. जो भी अन्य काम डीओएम या स्टाइल को अपडेट नहीं करते वे अगले फ़्रेम को पेंट करने में बेवजह देरी करेंगे, इसलिए सावधान रहें!

नतीजा

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

Unsplash से ली गई हीरो इमेज, जिसे फ़ेडरिको रेस्पिनी ने बनाया है.