अपनी वेबसाइट के फ़ील्ड डेटा में धीमे इंटरैक्शन का पता लगाने का तरीका जानें, ताकि आप इसके इंटरैक्शन टू नेक्स्ट पेंट को बेहतर बना सकें.
फ़ील्ड डेटा वह डेटा है जिससे आपको पता चलता है कि असल उपयोगकर्ताओं को आपकी वेबसाइट कैसा महसूस हो रही है. यह उन समस्याओं के बारे में बताता है जो आपको अकेले लैब डेटा में नहीं मिलेंगी. जहां इंटरैक्शन टू नेक्स्ट पेंट (आईएनपी) का सवाल है, वहां धीमे इंटरैक्शन की पहचान करने के लिए फ़ील्ड डेटा ज़रूरी होता है. साथ ही, यह समस्या को ठीक करने के लिए ज़रूरी संकेत देता है.
इस गाइड में आपको Chrome के लिए उपयोगकर्ता अनुभव से जुड़ी रिपोर्ट (CrUX) के फ़ील्ड डेटा का इस्तेमाल करके, अपनी वेबसाइट के आईएनपी का तेज़ी से आकलन करने का तरीका पता चलेगा. इससे यह पता चलेगा कि आपकी वेबसाइट पर आईएनपी से जुड़ी समस्याएं हैं या नहीं. इसके बाद, आपको वेब-वाइटल JavaScript लाइब्रेरी के एट्रिब्यूशन बिल्ड को इस्तेमाल करने के तरीके के बारे में जानकारी मिलेगी. साथ ही, यह भी जाना जाएगा कि आपकी वेबसाइट पर धीमे इंटरैक्शन के लिए फ़ील्ड डेटा को इकट्ठा करने और समझने के लिए, लॉन्ग ऐनिमेशन फ़्रेम एपीआई (LoAF) से मिली नई इनसाइट को कैसे इस्तेमाल करना है.
अपनी वेबसाइट के आईएनपी का आकलन करने के लिए, CrUX से शुरुआत करें
अगर वेबसाइट के उपयोगकर्ताओं से फ़ील्ड डेटा इकट्ठा नहीं किया जा रहा है, तो CrUX बेहतर हो सकता है. CrUX, Chrome के उन असली उपयोगकर्ताओं का फ़ील्ड डेटा इकट्ठा करता है जिन्होंने टेलीमेट्री डेटा भेजने का विकल्प चुना है.
CrUX डेटा कई अलग-अलग पहलुओं में दिखाया जाता है. यह उस जानकारी पर निर्भर करता है जिसकी आपको तलाश है. CrUX में, आईएनपी और वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी से जुड़ा डेटा इन चीज़ों के लिए उपलब्ध कराया जा सकता है:
- PageSpeed Insights का इस्तेमाल करके अलग-अलग पेज और पूरे ऑरिजिन.
- पेज किस तरह के होते हैं. उदाहरण के लिए, कई ई-कॉमर्स वेबसाइटों में प्रॉडक्ट विवरण पेज और प्रॉडक्ट लिस्टिंग पेज टाइप होते हैं. आपको Search Console में, यूनीक पेज टाइप के लिए CrUX डेटा मिल सकता है.
शुरुआत में, PageSpeed Insights में अपनी वेबसाइट का यूआरएल डाला जा सकता है. यूआरएल डालने के बाद, उसके लिए फ़ील्ड डेटा—अगर उपलब्ध हो—को आईएनपी के साथ-साथ कई मेट्रिक के लिए दिखाया जाएगा. मोबाइल और डेस्कटॉप डाइमेंशन के लिए आईएनपी वैल्यू देखने के लिए भी टॉगल का इस्तेमाल किया जा सकता है.
![फ़ील्ड डेटा को PageSpeed Insights में CrUX के ज़रिए दिखाया गया है. इसमें वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी देने वाली तीन मेट्रिक के तौर पर LCP, INP, CLS, और TTFB, FCP को डाइग्नोस्टिक्स मेट्रिक के तौर पर, और FID को काम न करने वाली कोर वेब वाइटल मेट्रिक के तौर पर दिखाया गया है.](https://web.dev/static/articles/find-slow-interactions-in-the-field/image/fig-1.png?authuser=6&hl=hi)
यह डेटा उपयोगी है, क्योंकि इससे आपको समस्या के बारे में पता चलता है. हालांकि, CrUX क्या नहीं कर सकता, इससे आपको यह पता चलता है कि समस्या किस वजह से हो रही है. ऐसे कई रीयल यूज़र मॉनिटरिंग (आरयूएम) समाधान उपलब्ध हैं जिनकी मदद से, अपनी वेबसाइट के उपयोगकर्ताओं से अपना फ़ील्ड डेटा इकट्ठा किया जा सकता है, ताकि इसका जवाब देने में आपको मदद मिल सके. इसके लिए, वेब-वाइटल JavaScript लाइब्रेरी का इस्तेमाल करके, उस फ़ील्ड डेटा को खुद इकट्ठा किया जा सकता है.
web-vitals
JavaScript लाइब्रेरी की मदद से फ़ील्ड डेटा इकट्ठा करें
web-vitals
JavaScript लाइब्रेरी एक ऐसी स्क्रिप्ट है जिसे अपनी वेबसाइट पर लोड करके, वेबसाइट के उपयोगकर्ताओं से फ़ील्ड डेटा इकट्ठा किया जा सकता है. इसका इस्तेमाल कई मेट्रिक रिकॉर्ड करने के लिए किया जा सकता है. इसमें, आईएनपी मेट्रिक को उन ब्राउज़र में रिकॉर्ड करना भी शामिल है जिन पर यह सुविधा काम करती है.
वेब-वाइटल लाइब्रेरी के स्टैंडर्ड बिल्ड का इस्तेमाल, फ़ील्ड के उपयोगकर्ताओं से आईएनपी का बुनियादी डेटा पाने के लिए किया जा सकता है:
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) दिखाता है. इसमें यह वैल्यू, आईएनपी थ्रेशोल्ड (अच्छी) के अंदर रहती है. साथ ही, एट्रिब्यूशन ऑब्जेक्ट में दिखाई गई अलग-अलग जानकारी के अलग-अलग बिट भी दिखते हैं. इसमें, लंबे ऐनिमेशन फ़्रेम एपीआई से मिली एंट्री भी शामिल हैं.](https://web.dev/static/articles/find-slow-interactions-in-the-field/image/fig-2.png?authuser=6&hl=hi)
पेज की आईएनपी मेट्रिक के अलावा, एट्रिब्यूशन बिल्ड काफ़ी डेटा उपलब्ध कराता है. इसकी मदद से, धीमे इंटरैक्शन की वजहों को समझा जा सकता है. इसमें यह भी शामिल होता है कि आपको इंटरैक्शन के किस हिस्से पर ध्यान देना चाहिए. इससे आपको कुछ अहम सवालों के जवाब पाने में मदद मिल सकती है. जैसे:
- "क्या पेज लोड होने के दौरान, उपयोगकर्ता ने उससे इंटरैक्ट किया?"
- "क्या इंटरैक्शन के इवेंट हैंडलर लंबे समय तक चले?"
- "क्या इंटरैक्शन इवेंट हैंडलर कोड को शुरू होने में देरी हुई? अगर हां, तो उस समय मुख्य थ्रेड में और क्या हो रहा था?"
- "क्या इंटरैक्शन की वजह से रेंडर करने में बहुत ज़्यादा काम हुआ, जिसकी वजह से अगला फ़्रेम पेंट नहीं हो पाया?"
नीचे दी गई टेबल में कुछ बुनियादी एट्रिब्यूशन डेटा दिखाया गया है, जो आपको लाइब्रेरी से मिल सकता है. इसकी मदद से, वेबसाइट पर धीमे इंटरैक्शन की कुछ हाई-लेवल वजहों का पता लगाया जा सकता है:
attribution ऑब्जेक्ट कुंजी
|
Data |
---|---|
interactionTarget
|
पेज की आईएनपी वैल्यू देने वाले एलिमेंट की ओर इशारा करने वाला सीएसएस सिलेक्टर—उदाहरण के लिए, button#save .
|
interactionType
|
क्लिक, टैप या कीबोर्ड इनपुट से मिले इंटरैक्शन का टाइप. |
inputDelay *
|
इंटरैक्शन का इनपुट देरी. |
processingDuration *
|
उपयोगकर्ता के इंटरैक्शन की प्रतिक्रिया में, पहले इवेंट की लिसनर के चलने का समय से लेकर, सभी इवेंट लिसनर की प्रोसेसिंग पूरी होने तक का समय. |
presentationDelay *
|
इंटरैक्शन की प्रज़ेंटेशन में देरी, जो इवेंट हैंडलर के पूरा होने से लेकर, अगले फ़्रेम को पेंट किए जाने के समय तक शुरू होती है. |
longAnimationFrameEntries *
|
इंटरैक्शन से जुड़ी LoAF की एंट्री. ज़्यादा जानकारी के लिए, अगली जानकारी देखें. |
वेब-वाइटल लाइब्रेरी के वर्शन 4 से, आईएनपी फ़ेज़ ब्रेकडाउन (इनपुट में देरी, प्रोसेसिंग अवधि, और प्रज़ेंटेशन में देरी) और लॉन्ग ऐनिमेशन फ़्रेम एपीआई (LoAF) के ज़रिए मिलने वाले डेटा के ज़रिए, आपको समस्या वाले इंटरैक्शन की ज़्यादा बेहतर जानकारी मिल सकती है.
द लॉन्ग ऐनिमेशन फ़्रेम्स एपीआई (LoAF)
फ़ील्ड डेटा का इस्तेमाल करके इंटरैक्शन डीबग करना मुश्किल होता है. हालांकि, अब एलओएएफ़ से मिले डेटा की मदद से, धीमे इंटरैक्शन की वजहों के बारे में बेहतर जानकारी मिल सकती है. ऐसा इसलिए, क्योंकि एलओएएफ़ कई टाइमिंग और अन्य डेटा उपलब्ध कराता है, जिसका इस्तेमाल सटीक वजहों का पता लगाने के लिए किया जा सकता है. सबसे अहम बात यह है कि समस्या की वजह आपकी वेबसाइट का कोड है.
वेब-वाइटल लाइब्रेरी के एट्रिब्यूशन बिल्ड से, attribution
ऑब्जेक्ट की longAnimationFrameEntries
कुंजी में LoAF की एंट्री का पता चलता है. नीचे दी गई टेबल में, एलओएएफ़ एंट्री में मिलने वाले डेटा के कुछ अहम हिस्सों की सूची दी गई है:
LoAF एंट्री ऑब्जेक्ट कुंजी | Data |
---|---|
duration
|
लंबे एनिमेशन फ़्रेम की अवधि, लेआउट खत्म होने तक, लेकिन पेंटिंग और कंपोज़िटिंग को छोड़कर. |
blockingDuration
|
उस फ़्रेम में कुल समय जिसमें ब्राउज़र, लंबे टास्क की वजह से तुरंत जवाब नहीं दे सका. ब्लॉक करने के इस समय में, JavaScript पर चलने वाले लंबे टास्क के साथ-साथ फ़्रेम में लंबे समय तक रेंडर होने वाले टास्क भी शामिल हो सकते हैं. |
firstUIEventTimestamp
|
फ़्रेम के दौरान, इवेंट की सूची में बनाए गए इवेंट का टाइमस्टैंप. इंटरैक्शन के इनपुट में देरी का पता लगाने में इससे मदद मिलती है. |
startTime
|
फ़्रेम का शुरुआती टाइमस्टैंप. |
renderStart
|
फ़्रेम के लिए रेंडरिंग का काम शुरू होने पर. इसमें कोई भी requestAnimationFrame कॉलबैक (और अगर लागू हो, तो ResizeObserver कॉलबैक) शामिल होते हैं. हालांकि, यह किसी भी स्टाइल/लेआउट के काम के शुरू होने से पहले हो सकता है.
|
styleAndLayoutStart
|
फ़्रेम में स्टाइल/लेआउट पर काम होने पर. अन्य उपलब्ध टाइमस्टैंप लगाते समय, स्टाइल/लेआउट की लंबाई का पता लगाने में इससे मदद मिल सकती है. |
scripts
|
आइटम का कलेक्शन, जिसमें पेज के आईएनपी में योगदान देने वाली स्क्रिप्ट के एट्रिब्यूशन की जानकारी शामिल है. |
![LoAF मॉडल के हिसाब से, लंबे ऐनिमेशन फ़्रेम का विज़ुअलाइज़ेशन.](https://web.dev/static/articles/find-slow-interactions-in-the-field/image/fig-3.png?authuser=6&hl=hi)
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
});
धीमे इंटरैक्शन की मुख्य वजह यह हो सकती है कि आपके इवेंट हैंडलर कोड को चलाने में ज़्यादा समय लगा, लेकिन हमेशा ऐसा नहीं होता! इस समस्या की पुष्टि होने के बाद, एलओएएफ़ डेटा की मदद से ज़्यादा जानकारी पाई जा सकती है:
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'
}
});
जैसा कि पिछले कोड स्निपेट में देखा जा सकता है, एलओएफ़ए डेटा की मदद से, प्रोसेस होने में लगने वाले ज़्यादा समय वाली वैल्यू वाले इंटरैक्शन की असल वजह को ट्रैक किया जा सकता है. इसमें ये शामिल हैं:
- एलिमेंट और रजिस्टर किए गए इवेंट लिसनर.
- स्क्रिप्ट फ़ाइल—और उसमें मौजूद वर्ण की जगह, जिसमें लंबे समय तक चलने वाला इवेंट हैंडलर कोड शामिल होता है.
- फ़ंक्शन का नाम.
इस तरह का डेटा बेशकीमती है. अब आपको यह पता लगाने की ज़रूरत नहीं है कि असल में किस इंटरैक्शन—या उसके कौनसे इवेंट हैंडलर—प्रोसेसिंग अवधि वाले ज़्यादा मान के लिए ज़िम्मेदार थे. साथ ही, तीसरे पक्ष की स्क्रिप्ट अक्सर अपने खुद के इवेंट हैंडलर रजिस्टर कर सकती हैं, इसलिए यह तय किया जा सकता है कि इसके लिए आपका कोड ज़िम्मेदार था या नहीं! आपके पास जिस कोड का कंट्रोल है उसके लिए, हो सकता है कि आप लंबे टास्क को ऑप्टिमाइज़ करने पर ध्यान देना चाहें.
लॉन्ग इनपुट डिले
हालांकि, लंबे समय तक चलने वाले इवेंट हैंडलर आम बात है, लेकिन इंटरैक्शन के अन्य हिस्सों पर भी विचार किया जाना चाहिए. एक हिस्सा, प्रोसेस होने से पहले का होता है. इसे इनपुट में देरी कहा जाता है. यह वह समय है जब उपयोगकर्ता इंटरैक्शन शुरू करता है और उस समय तक जब मुख्य थ्रेड पहले से ही किसी दूसरे टास्क को प्रोसेस कर रहा होता है. इवेंट हैंडलर कॉलबैक चलने लगते हैं. वेब-वाइटल लाइब्रेरी के एट्रिब्यूशन बिल्ड से आपको यह पता चल सकता है कि किसी इंटरैक्शन के लिए कितने समय में इनपुट में देरी हुई:
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 साइज़ शामिल हैं. वेब-वाइटल लाइब्रेरी में दिखने वाली, एलओएएफ़ टाइमिंग की मदद से, इस काम के लिए तय की गई अवधि को मापा जा सकता है:
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 आपको किसी फ़्रेम के लिए स्टाइल और लेआउट के काम की अवधि के बारे में नहीं बताएगा, लेकिन यह आपको बताएगा कि इसके शुरू होने का समय क्या है. इस शुरुआती टाइमस्टैंप की मदद से, एलओएएफ़ के अन्य डेटा का इस्तेमाल करके, फ़्रेम के खत्म होने का समय पता किया जा सकता है. इसके बाद, स्टाइल और लेआउट वर्क के शुरुआती टाइमस्टैंप को घटा दिया जा सकता है.
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 की सेवा देने वाली कंपनी जैसे फ़ील्ड डेटा इकट्ठा करने वाले टूल का इस्तेमाल करके, यह पता किया जा सकता है कि किन इंटरैक्शन से सबसे ज़्यादा समस्या आ रही है. इसके बाद, लैब में समस्या वाले इंटरैक्शन को बढ़ावा देना पर जाएं और उन्हें ठीक करें.
Federico Respini की Unस्प्लैश की हीरो इमेज.