खराब आईएनपी की वजहों का पता लगाना

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

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

Event Timing API की मदद से, आईएनपी की अवधि को तीन हिस्सों में बांटा जा सकता है: इनपुट में लगने वाला समय (इंटरैक्शन होने पर पहले से हो रही प्रोसेसिंग), प्रोसेसिंग में लगने वाला समय (इंटरैक्शन के सीधे नतीजे की वजह से होने वाली देरी), और प्रज़ेंटेशन में लगने वाला समय (इंटरैक्शन के बाद अगले फ़्रेम को रेंडर करने की वजह से होने वाली देरी). इससे यह पता लगाने में मदद मिलती है कि समस्या किसी अन्य कोड में है, इंटरैक्शन JavaScript कोड में है या ब्राउज़र प्रोसेसिंग रेंडरिंग अपडेट में है. इससे सीधे इंटरैक्शन कोड पर जाने की ज़रूरत नहीं पड़ती.

JavaScript, स्टाइल को फिर से कैलकुलेट करने, और लेआउट के काम में होने वाली देरी के बारे में ज़्यादा जानकारी इकट्ठा की जा सकती है. JS सेल्फ़-प्रोफ़ाइलिंग एपीआई का इस्तेमाल करके, परफ़ॉर्मेंस को पूरी तरह से ट्रेस करना एक मुश्किल काम है. इससे परफ़ॉर्मेंस से जुड़ी समस्याएं हो सकती हैं. Long Animation Frames API एक लाइटवेट एपीआई है. इसका इस्तेमाल, फ़ील्ड में धीमी गति से चलने वाली JavaScript की पहचान करने के लिए किया जा सकता है. साथ ही, आईएनपी इंटरैक्शन के दौरान, स्टाइल को फिर से कैलकुलेट करने और लेआउट की लागत के बीच अंतर करने के लिए किया जा सकता है:

  • स्क्रिप्ट-लेवल पर फ़ोर्स किया गया स्टाइल और लेआउट (forcedStyleDuration और forcedLayoutDuration): यह इनपुट में लगने वाले समय या प्रोसेसिंग में लगने वाले समय के दौरान, चल रही स्क्रिप्ट में सिंक्रोनस स्टाइल के फिर से कैलकुलेशन (जैसे, डीओएम म्यूटेशन के बाद getComputedStyle() को कॉल करना) और फ़ोर्स किए गए लेआउट/रीफ़्लो (जैसे, म्यूटेशन के बाद getBoundingClientRect() या offsetWidth को पढ़ना) की रिपोर्ट करता है.
  • फ़्रेम-लेवल रेंडरिंग स्टाइल और लेआउट (styleDuration और layoutDuration): यह फ़्रेम के रेंडरिंग अपडेट के दौरान, स्टाइल को फिर से कैलकुलेट करने और लेआउट को अपडेट करने में लगने वाले समय की जानकारी देता है. इससे, प्रज़ेंटेशन में ज़्यादा देरी होने की वजह को समझने में मदद मिलती है.

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

इन्हें कैसे लागू करें

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

web-vitals, Google की एक ओपन-सोर्स लाइब्रेरी है. यह Core Web Vitals का हिसाब लगाती है. इसमें आईएनपी भी शामिल है. साथ ही, इसमें आईएनपी इंटरैक्शन के लिए, सबपार्ट और लंबे ऐनिमेशन फ़्रेम का डेटा भी शामिल होता है.

web-vitals लाइब्रेरी का इस्तेमाल करके, आईएनपी इंटरैक्शन के लिए एट्रिब्यूशन पाना

web-vitals लाइब्रेरी एक छोटी लाइब्रेरी है. इसका इस्तेमाल, Core Web Vitals और अन्य परफ़ॉर्मेंस मेट्रिक को मेज़र करने के लिए किया जाता है. onINP() फ़ंक्शन का इस्तेमाल करके, सबसे धीमी इंटरैक्शन की पहचान की जा सकती है. इसमें आईएनपी के सबपार्ट, इंटरैक्शन के दौरान चलाए गए स्क्रिप्ट, और Long Animation Frames API का इस्तेमाल करके स्टाइल और लेआउट की अवधि के बारे में जानकारी शामिल होती है.

// Use the attribution build to get Long Animation Frame data
// alongside the INP metric value.
import { onINP } from 'web-vitals/attribution';

onINP((metric) => {
  const { attribution } = metric;
  const longestScript = attribution.longestScript;

  // Sum rendering-phase style and layout durations across all LoAF entries
  // intersecting the INP interaction (primarily explains presentationDelay).
  let renderStyleDuration = 0;
  let renderLayoutDuration = 0;
  for (const entry of attribution.longAnimationFrameEntries) {
    renderStyleDuration += entry.styleDuration ?? 0;
    renderLayoutDuration += entry.layoutDuration ?? 0;
  }

  // Beacon script, style, and layout attribution for the INP interaction,
  // so you can identify the root cause in production.
  navigator.sendBeacon(
    '/analytics',
    JSON.stringify({
      name: 'INP',
      value: metric.value,
      // These fields give the INP subparts:
      inputDelay: attribution.inputDelay,
      presentationDelay: attribution.presentationDelay,
      processingDuration: attribution.processingDuration,
      interactionTarget: attribution.interactionTarget,
      // These fields identify which script function was responsible
      // for the longest processing during the INP interaction.
      invokerType: longestScript?.entry?.invokerType,
      sourceURL: longestScript?.entry?.sourceURL,
      sourceFunctionName: longestScript?.entry?.sourceFunctionName,
      sourceCharPosition: longestScript?.entry?.sourceCharPosition,
      // subpart indicates which phase (input delay, processing, or
      // presentation delay) the longest script overlapped with most.
      subpart: longestScript?.subpart,
      intersectingDuration: longestScript?.intersectingDuration,
      // Synchronous style and layout work forced inside the longest script
      // (with forcedStyleAndLayoutDuration as a combined fallback):
      forcedStyleDuration: longestScript?.entry?.forcedStyleDuration,
      forcedLayoutDuration: longestScript?.entry?.forcedLayoutDuration,
      forcedStyleAndLayoutDuration: longestScript?.entry?.forcedStyleAndLayoutDuration,
      // Rendering-phase style and layout work across the interaction's frames
      // (with totalStyleAndLayoutDuration as a combined fallback):
      renderStyleDuration,
      renderLayoutDuration,
      totalStyleAndLayoutDuration: attribution.totalStyleAndLayoutDuration
    })
  );
});

सबसे सही तरीके

  • शुरुआत में आईएनपी के सबपार्ट का इस्तेमाल करके यह पता लगाएं कि देरी की वजह क्या है. जैसे, पहले से चल रही JavaScript (इनपुट में देरी), इंटरैक्शन के लिए इवेंट हैंडलर JavaScript (प्रोसेसिंग में लगने वाला समय) या बाद में रेंडरिंग (प्रज़ेंटेशन में देरी).
  • ज़रूर करें: ज़्यादा जानकारी के तौर पर, सबसे ज़्यादा ब्लॉक करने वाली JavaScript की पहचान करने की कोशिश करें. खास तौर पर, इनपुट डिले और प्रोसेसिंग में लगने वाले समय के लिए.
  • ज़रूर करें: प्रोसेसिंग में लगने वाले ज़्यादा समय या प्रज़ेंटेशन में होने वाली देरी का पता लगाते समय, स्टाइल को फिर से कैलकुलेट करने (styleDuration, forcedStyleDuration) और लेआउट (layoutDuration, forcedLayoutDuration) के बीच अंतर करें: स्टाइल में लगने वाला ज़्यादा समय, महंगे सीएसएस सिलेक्टर या बड़े पैमाने पर अमान्य होने का संकेत देता है. वहीं, लेआउट में लगने वाला ज़्यादा समय, डीओएम ज्यामिति की रुकावटों या सिंक्रोनस लेआउट थ्रैशिंग का संकेत देता है.
  • इस बारे में ज़्यादा जानकारी देने के लिए, JS सेल्फ़-प्रोफ़ाइलिंग एपीआई जैसे विकल्पों के बजाय, लंबे ऐनिमेशन फ़्रेम एपीआई को प्राथमिकता दें. JS सेल्फ़-प्रोफ़ाइलिंग एपीआई में रनटाइम ओवरहेड ज़्यादा होता है.
  • ज़रूर: अगर आरयूएम का कोई दूसरा समाधान मौजूद नहीं है, तो web-vitals लाइब्रेरी का इस्तेमाल करें. यह आईएनपी इंटरैक्शन की पहचान कर सकता है. साथ ही, इसमें इंटरैक्शन के दौरान इस्तेमाल किए गए सबपार्ट और स्क्रिप्ट की जानकारी शामिल होती है. इसके लिए, Long Animation Frames API का इस्तेमाल किया जाता है.
  • ज़रूर करें: ज़रूरी जानकारी को सिर्फ़ स्थानीय तौर पर लॉग करने के बजाय, उसे किसी Analytics सेवा को बीकन करें.

ब्राउज़र से जुड़ी सहायता और फ़ॉलबैक रणनीतियां

Event Timing API, ज़्यादातर मॉडर्न ब्राउज़र में उपलब्ध है. यह आईएनपी और आईएनपी के सबपार्ट का हिसाब लगाने के लिए ज़रूरी है. इस एपीआई के साथ काम न करने वाले ब्राउज़र के लिए, आईएनपी को मेज़र नहीं किया जा सकता.

Long Animation Frames API, ज़रूरी नहीं होने वाली अतिरिक्त जानकारी देता है. इसका इस्तेमाल, फ़ॉलबैक के बिना सुरक्षित तरीके से किया जा सकता है. ज़्यादातर मामलों में, परफ़ॉर्मेंस को बेहतर बनाने के लिए जो अवसर यह पहचानता है वे अन्य ब्राउज़र पर भी लागू होंगे.

अगर आपका बेसलाइन टारगेट, Long Animation Frames API (long-animation-frames) के साथ काम करता है, लेकिन स्टाइल और लेआउट की अवधि वाली अलग-अलग प्रॉपर्टी (PerformanceLongAnimationFrameTiming पर styleDuration और layoutDuration या PerformanceScriptTiming पर forcedStyleDuration और forcedLayoutDuration) के साथ काम नहीं करता है, तो स्टाइल और लेआउट के लिए कंबाइन की गई समयावधि पर वापस जाएं:

  • स्क्रिप्ट में सिंक्रोनस फ़ोर्स्ड स्टाइल और लेआउट के लिए, PerformanceScriptTiming पर script.forcedStyleAndLayoutDuration का इस्तेमाल करें.
  • स्टाइल और लेआउट को एक साथ इस्तेमाल करने के लिए, web-vitals/attribution में metric.attribution.totalStyleAndLayoutDuration का इस्तेमाल करें या हर PerformanceLongAnimationFrameTiming एंट्री पर (entry.paintTime || entry.startTime + entry.duration) - entry.styleAndLayoutStart का हिसाब लगाएं.