उपयोगकर्ता पर आधारित मेट्रिक का इस्तेमाल करने से काफ़ी फ़ायदा होता है. इन मेट्रिक को किसी भी वेबसाइट पर, सभी के लिए मेज़र किया जा सकता है. इन मेट्रिक की मदद से:
- जानें कि असली उपयोगकर्ताओं को वेब पर कैसा अनुभव मिलता है.
- अपनी साइट की तुलना किसी दूसरे कारोबार की साइट से करें.
- कस्टम कोड लिखे बिना, अपने आंकड़ों के टूल में काम का और कार्रवाई लायक डेटा ट्रैक करें.
यूनिवर्सल मेट्रिक से आपको अच्छा बेसलाइन मिलता है. हालांकि, कई मामलों में आपको अपनी साइट के पूरे अनुभव को कैप्चर करने के लिए, सिर्फ़ इन मेट्रिक के अलावा ज़्यादा मेट्रिक को मेज़र करना होगा.
कस्टम मेट्रिक की मदद से, अपनी साइट पर आने वाले लोगों के अनुभव के उन पहलुओं को मेज़र किया जा सकता है जो सिर्फ़ आपकी साइट पर लागू होते हैं. जैसे:
- किसी एक पेज के ऐप्लिकेशन (एसपीए) को एक "पेज" से दूसरे पर ट्रांज़िशन होने में कितना समय लगता है.
- लॉग इन किए हुए उपयोगकर्ताओं के लिए, किसी डेटाबेस से फ़ेच किए गए डेटा को पेज पर दिखाने में कितना समय लगता है.
- सर्वर साइड रेंडरिंग (एसएसआर) वाले ऐप्लिकेशन को हाइड्रेट होने में कितना समय लगता है.
- वेबसाइट पर वापस आने वाले लोगों से लोड किए गए रिसॉर्स के लिए, कैश मेमोरी हिट रेट.
- किसी गेम में क्लिक या कीबोर्ड इवेंट के रिस्पॉन्स में लगने वाला समय.
कस्टम मेट्रिक को मेज़र करने के लिए एपीआई
पहले, वेब डेवलपर के पास परफ़ॉर्मेंस मेज़र करने के लिए, कम लेवल के कई एपीआई नहीं थे. इस वजह से, उन्हें यह मेज़र करने के लिए हैक का सहारा लेना पड़ता था कि कोई साइट अच्छी परफ़ॉर्म कर रही है या नहीं.
उदाहरण के लिए, requestAnimationFrame
लूप चलाकर और हर फ़्रेम के बीच के डेल्टा का हिसाब लगाकर, यह पता लगाया जा सकता है कि लंबे समय तक चलने वाले JavaScript टास्क की वजह से मुख्य थ्रेड ब्लॉक हुआ है या नहीं. अगर डेल्टा, डिसप्ले के फ़्रेम रेट से काफ़ी ज़्यादा है, तो इसकी शिकायत लंबे टास्क के तौर पर की जा सकती है. हालांकि, हम ऐसे हैक इस्तेमाल करने का सुझाव नहीं देते, क्योंकि इनसे परफ़ॉर्मेंस पर असर पड़ता है. उदाहरण के लिए, बैटरी खर्च होना.
परफ़ॉर्मेंस को असरदार तरीके से मेज़र करने का पहला नियम यह पक्का करना है कि परफ़ॉर्मेंस मेज़र करने की आपकी तकनीकों की वजह से, परफ़ॉर्मेंस में कोई समस्या न हो. इसलिए, अपनी साइट पर मेज़र की जाने वाली किसी भी कस्टम मेट्रिक के लिए, अगर हो सके, तो इनमें से किसी एक एपीआई का इस्तेमाल करना सबसे अच्छा है.
परफ़ॉर्मेंस ऑब्ज़र्वर एपीआई
परफ़ॉर्मेंस ऑब्ज़र्वर एपीआई एक ऐसा तरीका है जो इस पेज पर बताए गए अन्य सभी परफ़ॉर्मेंस एपीआई से डेटा इकट्ठा करता है और उसे दिखाता है. अच्छा डेटा पाने के लिए, इसे समझना ज़रूरी है.
परफ़ॉर्मेंस से जुड़े इवेंट की पैसिव सदस्यता लेने के लिए, PerformanceObserver
का इस्तेमाल किया जा सकता है. इससे इडल पीरियड के दौरान एपीआई कॉलबैक ट्रिगर हो सकते हैं. इसका मतलब है कि आम तौर पर, वे पेज की परफ़ॉर्मेंस में रुकावट नहीं डालेंगे.
PerformanceObserver
बनाने के लिए, उसे एक कॉलबैक पास करें, ताकि जब भी नई परफ़ॉर्मेंस एंट्री डिस्पैच की जाएं, तब वह कॉलबैक चलाया जा सके. इसके बाद, आपको observe()
तरीके का इस्तेमाल करके, ऑब्ज़र्वर को यह बताना होगा कि किस तरह की एंट्री को सुनना है:
const po = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// Log the entry and all associated details.
console.log(entry.toJSON());
}
});
po.observe({type: 'some-entry-type'});
नीचे दिए गए सेक्शन में, निगरानी के लिए उपलब्ध अलग-अलग एंट्री टाइप की सूची दी गई है. हालांकि, नए ब्राउज़र में, स्टैटिक PerformanceObserver.supportedEntryTypes
प्रॉपर्टी की मदद से यह जांचा जा सकता है कि कौनसे एंट्री टाइप उपलब्ध हैं.
पहले से मौजूद एंट्री देखना
डिफ़ॉल्ट रूप से, PerformanceObserver
ऑब्जेक्ट सिर्फ़ तब एंट्री देख सकते हैं, जब वे होती हैं. अगर आपको परफ़ॉर्मेंस के आंकड़े देने वाले कोड को धीरे-धीरे लोड करना है, तो इससे समस्याएं आ सकती हैं. ऐसा इसलिए, क्योंकि इससे ज़्यादा प्राथमिकता वाले संसाधन ब्लॉक हो सकते हैं.
पुरानी एंट्री देखने के लिए, observe()
को कॉल करते समय buffered
फ़्लैग को true
पर सेट करें. जब पहली बार आपके PerformanceObserver
कॉलबैक को कॉल किया जाएगा, तब ब्राउज़र अपने परफ़ॉर्मेंस एंट्री बफ़र से पुरानी एंट्री शामिल करेगा. हालांकि, यह उस टाइप के लिए बफ़र के ज़्यादा से ज़्यादा साइज़ तक ही शामिल करेगा.
po.observe({
type: 'some-entry-type',
buffered: true,
});
परफ़ॉर्मेंस से जुड़े ऐसे लेगसी एपीआई जिनका इस्तेमाल नहीं करना चाहिए
परफ़ॉर्मेंस ऑब्ज़र्वर एपीआई से पहले, डेवलपर performance
ऑब्जेक्ट पर बताए गए इन तीन तरीकों का इस्तेमाल करके, परफ़ॉर्मेंस एंट्री ऐक्सेस कर सकते थे:
इन एपीआई का इस्तेमाल अब भी किया जा सकता है. हालांकि, हमारा सुझाव है कि इनका इस्तेमाल न करें, क्योंकि इनकी मदद से यह पता नहीं लगाया जा सकता कि नई एंट्री कब जनरेट हुई हैं. इसके अलावा, कई नए एपीआई (जैसे, largest-contentful-paint
) performance
ऑब्जेक्ट के ज़रिए एक्सपोज़ नहीं किए जाते. ये सिर्फ़ PerformanceObserver
के ज़रिए एक्सपोज़ किए जाते हैं.
अगर आपको खास तौर पर Internet Explorer के साथ काम करने की ज़रूरत नहीं है, तो अपने कोड में इन तरीकों का इस्तेमाल न करें. इसके बजाय, आगे PerformanceObserver
का इस्तेमाल करें.
User Timing API
User Timing API, समय पर आधारित मेट्रिक के लिए, सामान्य मकसद वाला मेज़रमेंट एपीआई है. इसकी मदद से, समय में अपनी पसंद के मुताबिक पॉइंट मार्क किए जा सकते हैं. इसके बाद, उन पॉइंट के बीच की अवधि को मेज़र किया जा सकता है.
// Record the time immediately before running a task.
performance.mark('myTask:start');
await doMyTask();
// Record the time immediately after running a task.
performance.mark('myTask:end');
// Measure the delta between the start and end of the task
performance.measure('myTask', 'myTask:start', 'myTask:end');
Date.now()
या performance.now()
जैसे एपीआई, आपको मिलती-जुलती सुविधाएं देते हैं. हालांकि, User Timing API का इस्तेमाल करने का फ़ायदा यह है कि यह परफ़ॉर्मेंस टूल के साथ अच्छी तरह से इंटिग्रेट होता है. उदाहरण के लिए, Chrome DevTools, परफ़ॉर्मेंस पैनल में उपयोगकर्ता के समय से जुड़े मेज़रमेंट को विज़ुअलाइज़ करता है. साथ ही, कई आंकड़े देने वाली कंपनियां, आपके किए गए किसी भी मेज़रमेंट को अपने-आप ट्रैक करेंगी और कुल समय का डेटा अपने आंकड़े देने वाले बैकएंड को भेजेंगी.
उपयोगकर्ता के समय से जुड़े मेज़रमेंट की रिपोर्ट करने के लिए, PerformanceObserver का इस्तेमाल करें. साथ ही, measure
टाइप की एंट्री को देखने के लिए रजिस्टर करें:
// Create the performance observer.
const po = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// Log the entry and all associated details.
console.log(entry.toJSON());
}
});
// Start listening for `measure` entries to be dispatched.
po.observe({type: 'measure', buffered: true});
Long Tasks API
लंबे समय तक चलने वाले टास्क के लिए एपीआई का इस्तेमाल करके, यह पता लगाया जा सकता है कि फ़्रेम रेट या इनपुट में लगने वाले समय पर असर डालने के लिए, ब्राउज़र का मुख्य थ्रेड कब तक ब्लॉक रहता है. एपीआई उन सभी टास्क की रिपोर्ट करेगा जो 50 मिलीसेकंड से ज़्यादा समय तक चलते हैं.
जब भी आपको ज़्यादा समय लेने वाला कोड चलाना हो या बड़ी स्क्रिप्ट लोड और एक्ज़ीक्यूट करनी हो, तो यह ट्रैक करना ज़रूरी है कि वह कोड मुख्य थ्रेड को ब्लॉक करता है या नहीं. असल में, कई बेहतर लेवल की मेट्रिक, Long Tasks API के ऊपर बनाई गई हैं. जैसे, इंटरैक्टिव होने में लगने वाला समय (टीटीआई) और ब्लॉक होने में लगने वाला कुल समय (टीबीटी).
यह पता लगाने के लिए कि लंबे टास्क कब होते हैं, PerformanceObserver का इस्तेमाल करें. साथ ही, longtask
टाइप की एंट्री को देखने के लिए रजिस्टर करें:
// Create the performance observer.
const po = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// Log the entry and all associated details.
console.log(entry.toJSON());
}
});
// Start listening for `longtask` entries to be dispatched.
po.observe({type: 'longtask', buffered: true});
Long Animation Frames API
Long Animation Frames API, Long Tasks API का नया वर्शन है. यह 50 मिलीसेकंड से ज़्यादा के लंबे टास्क के बजाय, लंबे फ़्रेम पर नज़र रखता है. इससे Long Tasks API की कुछ कमियों को ठीक किया जा सकता है. जैसे, बेहतर एट्रिब्यूशन और संभावित समस्याओं में देरी का दायरा बढ़ाना.
यह पता लगाने के लिए कि लंबे फ़्रेम कब होते हैं, PerformanceObserver का इस्तेमाल करें. साथ ही, long-animation-frame
टाइप की एंट्री को देखने के लिए रजिस्टर करें:
// Create the performance observer.
const po = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// Log the entry and all associated details.
console.log(entry.toJSON());
}
});
// Start listening for `long-animation-frame` entries to be dispatched.
po.observe({type: 'long-animation-frame', buffered: true});
Element Timing API
सबसे बड़े कॉन्टेंटफ़ुल पेंट (एलसीपी) मेट्रिक से यह पता चलता है कि स्क्रीन पर सबसे बड़ी इमेज या टेक्स्ट ब्लॉक को कब दिखाया गया. हालांकि, कुछ मामलों में आपको किसी दूसरे एलिमेंट के रेंडर होने में लगने वाले समय को मेज़र करना हो सकता है.
ऐसे मामलों के लिए, एलिमेंट टाइमिंग एपीआई का इस्तेमाल करें. एलसीपी एपीआई, असल में एलिमेंट टाइमिंग एपीआई के ऊपर बनाया गया है. यह सबसे बड़े कॉन्टेंट वाले एलिमेंट की रिपोर्टिंग अपने-आप जोड़ता है. हालांकि, अन्य एलिमेंट की रिपोर्टिंग भी की जा सकती है. इसके लिए, उनमें elementtiming
एट्रिब्यूट को साफ़ तौर पर जोड़ें और element
एंट्री टाइप को देखने के लिए, PerformanceObserver को रजिस्टर करें.
<img elementtiming="hero-image" />
<p elementtiming="important-paragraph">This is text I care about.</p>
<!-- ... -->
<script>
const po = new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
// Log the entry and all associated details.
console.log(entry.toJSON());
}
});
// Start listening for `element` entries to be dispatched.
po.observe({type: 'element', buffered: true});
</script>
इवेंट टाइमिंग एपीआई
पेज के रिस्पॉन्स में लगने वाला समय (आईएनपी) मेट्रिक, पेज पर रिस्पॉन्स मिलने में लगने वाले समय का आकलन करती है. इसके लिए, यह मेट्रिक पेज पर हुए सभी क्लिक, टैप, और कीबोर्ड इंटरैक्शन को ध्यान में रखती है. आम तौर पर, किसी पेज का आईएनपी वह इंटरैक्शन होता है जिसे पूरा करने में सबसे ज़्यादा समय लगता है. यह समय, उपयोगकर्ता के इंटरैक्शन शुरू करने से लेकर, ब्राउज़र के अगले फ़्रेम को पेंट करने तक का होता है. इस फ़्रेम में, उपयोगकर्ता के इनपुट का विज़ुअल नतीजा दिखता है.
INP मेट्रिक, इवेंट टाइमिंग एपीआई की मदद से जनरेट होती है. यह एपीआई, इवेंट के लाइफ़साइकल के दौरान होने वाले कई टाइमस्टैंप दिखाता है. इनमें ये शामिल हैं:
startTime
: वह समय जब ब्राउज़र को इवेंट मिलता है.processingStart
: वह समय जब ब्राउज़र, इवेंट के लिए इवेंट हैंडलर को प्रोसेस करना शुरू कर सकता है.processingEnd
: वह समय जब ब्राउज़र इस इवेंट के लिए, इवेंट हैंडलर से शुरू किए गए सभी सिंक्रोनस कोड को पूरा कर लेता है.duration
: ब्राउज़र को इवेंट मिलने से लेकर, इवेंट हैंडलर से शुरू किए गए सभी सिंक्रोनस कोड को पूरा करने के बाद अगला फ़्रेम पेंट करने में लगने वाला समय. सुरक्षा से जुड़ी वजहों से, इसे 8 मिलीसेकंड के आस-पास के राउंड में दिखाया जाता है.
नीचे दिए गए उदाहरण में, कस्टम मेज़रमेंट बनाने के लिए इन वैल्यू का इस्तेमाल करने का तरीका बताया गया है:
const po = new PerformanceObserver((entryList) => {
// Get the last interaction observed:
const entries = Array.from(entryList.getEntries()).forEach((entry) => {
// Get various bits of interaction data:
const inputDelay = entry.processingStart - entry.startTime;
const processingTime = entry.processingEnd - entry.processingStart;
const presentationDelay = entry.startTime + entry.duration - entry.processingEnd;
const duration = entry.duration;
const eventType = entry.name;
const target = entry.target || "(not set)"
console.log("----- INTERACTION -----");
console.log(`Input delay (ms): ${inputDelay}`);
console.log(`Event handler processing time (ms): ${processingTime}`);
console.log(`Presentation delay (ms): ${presentationDelay}`);
console.log(`Total event duration (ms): ${duration}`);
console.log(`Event type: ${eventType}`);
console.log(target);
});
});
// A durationThreshold of 16ms is necessary to include more
// interactions, since the default is 104ms. The minimum
// durationThreshold is 16ms.
po.observe({type: 'event', buffered: true, durationThreshold: 16});
Resource Timing API
रिसॉर्स टाइमिंग एपीआई, डेवलपर को इस बारे में पूरी जानकारी देता है कि किसी पेज के लिए रिसॉर्स कैसे लोड किए गए. इस एपीआई का नाम 'टाइमिंग डेटा' होने के बावजूद, यह सिर्फ़ टाइमिंग डेटा ही नहीं दिखाता. हालांकि, इसमें टाइमिंग डेटा काफ़ी होता है. आपके पास इस तरह का अन्य डेटा ऐक्सेस करने का विकल्प होता है:
initiatorType
: संसाधन को कैसे फ़ेच किया गया: जैसे,<script>
या<link>
टैग से याfetch()
कॉल से.nextHopProtocol
: संसाधन को फ़ेच करने के लिए इस्तेमाल किया जाने वाला प्रोटोकॉल, जैसे किh2
याquic
.encodedBodySize
/decodedBodySize]: एन्कोड किए गए या डिकोड किए गए फ़ॉर्म में, संसाधन का साइज़ (क्रमशः)transferSize
: नेटवर्क पर ट्रांसफ़र किए गए संसाधन का साइज़. जब कैश मेमोरी से संसाधनों की मांग पूरी की जाती है, तो यह वैल्यूencodedBodySize
से काफ़ी कम हो सकती है. साथ ही, कुछ मामलों में यह शून्य भी हो सकती है (अगर कैश मेमोरी की फिर से पुष्टि करने की ज़रूरत नहीं है).
कैश मेमोरी में डेटा सेव होने की दर मेट्रिक या कैश मेमोरी में सेव किए गए संसाधन का कुल साइज़ मेट्रिक को मेज़र करने के लिए, रिसॉर्स टाइमिंग एंट्री की transferSize
प्रॉपर्टी का इस्तेमाल किया जा सकता है. इससे यह समझने में मदद मिलती है कि रिसॉर्स को कैश मेमोरी में सेव करने की आपकी रणनीति से, बार-बार आने वाले लोगों की परफ़ॉर्मेंस पर क्या असर पड़ता है.
नीचे दिए गए उदाहरण में, पेज के अनुरोध किए गए सभी रिसॉर्स को लॉग किया गया है. साथ ही, यह भी बताया गया है कि कैश मेमोरी में सेव किए गए हर रिसॉर्स को लोड किया गया था या नहीं.
// Create the performance observer.
const po = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// If transferSize is 0, the resource was fulfilled using the cache.
console.log(entry.name, entry.transferSize === 0);
}
});
// Start listening for `resource` entries to be dispatched.
po.observe({type: 'resource', buffered: true});
Navigation Timing API
Navigation Timing API, Resource Timing API जैसा ही है. हालांकि, यह सिर्फ़ नेविगेशन अनुरोधों की रिपोर्ट करता है. navigation
एंट्री टाइप, resource
एंट्री टाइप से मिलता-जुलता है. हालांकि, इसमें सिर्फ़ नेविगेशन अनुरोधों के लिए कुछ अतिरिक्त जानकारी होती है. जैसे, DOMContentLoaded
और load
इवेंट ट्रिगर होने पर.
सर्वर के जवाब में लगने वाले समय (टाइम टू फ़र्स्ट बाइट (टीटीएफ़बी)) को समझने के लिए, कई डेवलपर एक मेट्रिक ट्रैक करते हैं. यह मेट्रिक, नेविगेशन टाइमिंग एपीआई का इस्तेमाल करके उपलब्ध होती है. खास तौर पर, इसकी एंट्री का responseStart
टाइमस्टैंप.
// Create the performance observer.
const po = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// If transferSize is 0, the resource was fulfilled using the cache.
console.log('Time to first byte', entry.responseStart);
}
});
// Start listening for `navigation` entries to be dispatched.
po.observe({type: 'navigation', buffered: true});
सर्विस वर्कर का इस्तेमाल करने वाले डेवलपर को नेविगेशन अनुरोधों के लिए, सर्विस वर्कर के शुरू होने में लगने वाला समय भी ध्यान में रखना चाहिए. फ़ेच इवेंट को इंटरसेप्ट करने से पहले, ब्राउज़र को सेवा वर्कर थ्रेड शुरू करने में लगने वाला समय.
किसी नेविगेशन अनुरोध के लिए, सेवा वर्कर के शुरू होने का समय, entry.responseStart
और entry.workerStart
के बीच के डेल्टा से तय किया जा सकता है.
// Create the performance observer.
const po = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log('Service Worker startup time:',
entry.responseStart - entry.workerStart);
}
});
// Start listening for `navigation` entries to be dispatched.
po.observe({type: 'navigation', buffered: true});
Server Timing API
सर्वर टाइमिंग एपीआई की मदद से, अनुरोध के हिसाब से टाइमिंग का डेटा, सर्वर से ब्राउज़र पर भेजा जा सकता है. इसके लिए, रिस्पॉन्स हेडर का इस्तेमाल किया जाता है. उदाहरण के लिए, किसी खास अनुरोध के लिए डेटाबेस में डेटा को लुकअप करने में कितना समय लगा, यह बताया जा सकता है. यह जानकारी, सर्वर के धीमे होने की वजह से परफ़ॉर्मेंस से जुड़ी समस्याओं को डीबग करने में मददगार हो सकती है.
तीसरे पक्ष के आंकड़े उपलब्ध कराने वाली कंपनियों का इस्तेमाल करने वाले डेवलपर के लिए, सर्वर की परफ़ॉर्मेंस के डेटा को कारोबार की उन अन्य मेट्रिक से जोड़ने का सिर्फ़ एक ही तरीका है जिन्हें ये आंकड़े उपलब्ध कराने वाले टूल मेज़र कर सकते हैं. इसके लिए, सर्वर टाइमिंग एपीआई का इस्तेमाल किया जाता है.
अपने जवाबों में सर्वर के टाइमिंग डेटा की जानकारी देने के लिए, Server-Timing
रिस्पॉन्स हेडर का इस्तेमाल किया जा सकता है. यहां एक उदाहरण दिया गया है.
HTTP/1.1 200 OK
Server-Timing: miss, db;dur=53, app;dur=47.2
इसके बाद, अपने पेजों पर, रिसॉर्स टाइमिंग और नेविगेशन टाइमिंग एपीआई की resource
या navigation
, दोनों एंट्री पर यह डेटा पढ़ा जा सकता है.
// Create the performance observer.
const po = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// Logs all server timing data for this response
console.log('Server Timing', entry.serverTiming);
}
});
// Start listening for `navigation` entries to be dispatched.
po.observe({type: 'navigation', buffered: true});