नेविगेशन समय और संसाधन समय की मदद से, फ़ील्ड में लोड होने की परफ़ॉर्मेंस का आकलन करना

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

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

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

एपीआई, जो फ़ील्ड में लोड होने की परफ़ॉर्मेंस का आकलन करने में आपकी मदद करते हैं

नेविगेशन टाइमिंग और रिसॉर्स टाइमिंग ऐसे दो मिलते-जुलते एपीआई हैं जिनके ओवरलैप होने की जानकारी दो अलग-अलग चीज़ों को मेज़र करती है:

  • नेविगेशन टाइमिंग, एचटीएमएल दस्तावेज़ों के अनुरोधों (जैसे कि नेविगेशन के अनुरोधों) की स्पीड को मेज़र करता है.
  • Resource Timing की मदद से, दस्तावेज़ पर आधारित संसाधनों, जैसे कि सीएसएस, JavaScript, इमेज वगैरह के लिए अनुरोधों की रफ़्तार मापी जाती है.

ये एपीआई अपने डेटा को परफ़ॉर्मेंस एंट्री बफ़र में दिखाते हैं. इसे ब्राउज़र में JavaScript से ऐक्सेस किया जा सकता है. परफ़ॉर्मेंस बफ़र के लिए क्वेरी करने के कई तरीके हैं, लेकिन एक सामान्य तरीका performance.getEntriesByType का इस्तेमाल करना है:

// Get Navigation Timing entries:
performance.getEntriesByType('navigation');

// Get Resource Timing entries:
performance.getEntriesByType('resource');

performance.getEntriesByType उस स्ट्रिंग को स्वीकार करता है जिसमें ऐसी एंट्री के टाइप के बारे में बताया गया है जिन्हें आपको परफ़ॉर्मेंस एंट्री बफ़र से वापस पाना है. 'navigation' और 'resource', नेविगेशन टाइमिंग और Resource Timing API के लिए टाइमिंग डेटा हासिल करते हैं.

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

नेटवर्क अनुरोध की अवधि और समय

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

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

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

DNS लुकअप

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

  • domainLookupStart तब शुरू होता है, जब डीएनएस लुकअप शुरू होता है.
  • domainLookupEnd तब होता है, जब डीएनएस लुकअप खत्म हो जाता है.

कुल डीएनएस लुकअप समय का हिसाब, आखिरी मेट्रिक से शुरुआती मेट्रिक को घटाकर किया जा सकता है:

// Measuring DNS lookup time
const [pageNav] = performance.getEntriesByType('navigation');
const totalLookupTime = pageNav.domainLookupEnd - pageNav.domainLookupStart;

कनेक्शन नेगोशिएशन

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

  • connectStart वह है, जब ब्राउज़र किसी वेब सर्वर से कनेक्शन खोलना शुरू करता है.
  • जब क्लाइंट TLS नेगोशिएशन शुरू करता है, तो secureConnectionStart मार्क किया जाता है.
  • connectEnd वह है, जब वेब सर्वर से कनेक्शन स्थापित हो जाता है.

कुल कनेक्शन समय को मापना कुल DNS लुकअप समय को मापने के समान है: आप शुरू होने के समय को खत्म होने के समय से घटाते हैं. हालांकि, एक अन्य secureConnectionStart प्रॉपर्टी है, जो 0 हो सकती है. ऐसा तब होता है, जब एचटीटीपीएस का इस्तेमाल न किया गया हो या कनेक्शन लगातार बना रहे. अगर आपको TLS से जुड़ी बातचीत के समय को मेज़र करना है, तो आपको यह ध्यान रखना होगा:

// Quantifying total connection time
const [pageNav] = performance.getEntriesByType('navigation');
const connectionTime = pageNav.connectEnd - pageNav.connectStart;
let tlsTime = 0; // <-- Assume 0 to start with

// Was there TLS negotiation?
if (pageNav.secureConnectionStart > 0) {
  // Awesome! Calculate it!
  tlsTime = pageNav.connectEnd - pageNav.secureConnectionStart;
}

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

अनुरोध और जवाब

कॉन्टेंट लोड होने की परफ़ॉर्मेंस पर दो तरह का असर पड़ता है:

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

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

  • जब ब्राउज़र, संसाधन (संसाधन समय) या नेविगेशन अनुरोध (नेविगेशन समय) के लिए कोई दस्तावेज़ फ़ेच करना शुरू करता है, तब fetchStart मार्क करता है. यह असल अनुरोध से पहले आता है और वह समय होता है जब ब्राउज़र कैश मेमोरी की जांच करता है. उदाहरण के लिए, एचटीटीपी और Cache इंस्टेंस.
  • जब किसी सर्विस वर्कर के fetch इवेंट हैंडलर में अनुरोध को हैंडल करना शुरू किया जाता है, तब workerStart मार्क करता है. जब कोई सर्विस वर्कर मौजूदा पेज को कंट्रोल नहीं कर रहा होगा, तब यह 0 होगा.
  • जब ब्राउज़र अनुरोध करता है, तो इसे requestStart कहते हैं.
  • जवाब का पहला बाइट मिलने पर responseStart होता है.
  • responseEnd, रिस्पॉन्स का आखिरी बाइट होने पर मिलता है.

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

// Cache seek plus response time of the current document
const [pageNav] = performance.getEntriesByType('navigation');
const fetchTime = pageNav.responseEnd - pageNav.fetchStart;

// Service worker time plus response time
let workerTime = 0;

if (pageNav.workerStart > 0) {
  workerTime = pageNav.responseEnd - pageNav.workerStart;
}

अनुरोध/रिस्पॉन्स में लगने वाले समय के अन्य पहलुओं को भी मेज़र किया जा सकता है:

const [pageNav] = performance.getEntriesByType('navigation');

// Request time only (excluding redirects, DNS, and connection/TLS time)
const requestTime = pageNav.responseStart - pageNav.requestStart;

// Response time only (download)
const responseTime = pageNav.responseEnd - pageNav.responseStart;

// Request + response time
const requestResponseTime = pageNav.responseEnd - pageNav.requestStart;

अन्य माप जो आप कर सकते हैं

नेविगेशन समय और संसाधन समय, ऊपर दिए गए उदाहरणों में बताए गए आंकड़ों से कहीं ज़्यादा काम के हैं. यहां कुछ और स्थितियों के बारे में बताया गया है, जिनके लिए समय तय करना सही होगा:

  • पेज रीडायरेक्ट: रीडायरेक्ट, देरी से मिलने वाले ऐसे सोर्स हैं जिन्हें अनदेखा किया गया है. खास तौर पर, रीडायरेक्ट चेन. इंतज़ार के समय को कई तरीकों से जोड़ा जाता है. जैसे, एचटीटीपी-से-एचटीटीपी हो जाने पर, 302/कैश मेमोरी में सेव नहीं किए गए 301 रीडायरेक्ट के ज़रिए. redirectStart, redirectEnd, और redirectCount टाइमिंग से, रीडायरेक्ट होने में लगने वाले समय का आकलन करने में मदद मिलती है.
  • दस्तावेज़ अनलोड करना: कोड को unload इवेंट हैंडलर में चलाने वाले पेजों पर, अगले पेज पर जाने से पहले ब्राउज़र को वह कोड चलाना होता है. unloadEventStart और unloadEventEnd, दस्तावेज़ की अनलोडिंग को मेज़र करते हैं.
  • दस्तावेज़ की प्रोसेसिंग: जब तक आपकी वेबसाइट बहुत ज़्यादा एचटीएमएल पेलोड नहीं भेजती, तब तक दस्तावेज़ की प्रोसेसिंग में लगने वाला समय नहीं जुड़ सकता. अगर यह आपकी स्थिति के बारे में बताता है, तो domInteractive, domContentLoadedEventStart, domContentLoadedEventEnd, और domComplete के समय में बदलाव किया जा सकता है.

ऐप्लिकेशन कोड में समय की जानकारी पाना

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

परफ़ॉर्मेंस एंट्री बफ़र से एंट्री इकट्ठा करने के लिए, PerformanceObserver का इस्तेमाल करने का सुझाव दिया जाता है. PerformanceObserver, परफ़ॉर्मेंस की एंट्री सुनता है और बफ़र में जोड़े जाने पर उन्हें उपलब्ध कराता है:

// Create the performance observer:
const perfObserver = new PerformanceObserver((observedEntries) => {
  // Get all resource entries collected so far:
  const entries = observedEntries.getEntries();

  // Iterate over entries:
  for (let i = 0; i < entries.length; i++) {
    // Do the work!
  }
});

// Run the observer for Navigation Timing entries:
perfObserver.observe({
  type: 'navigation',
  buffered: true
});

// Run the observer for Resource Timing entries:
perfObserver.observe({
  type: 'resource',
  buffered: true
});

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

फ़ोनिंग होम

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

// Caution: If you have lots of performance entries, don't
// do this. This is an example for illustrative purposes.
const data = JSON.stringify(performance.getEntries()));

// The endpoint to transmit the encoded data to
const endpoint = '/analytics';

// Check for fetch keepalive support
if ('keepalive' in Request.prototype) {
  fetch(endpoint, {
    method: 'POST',
    body: data,
    keepalive: true,
    headers: {
      'Content-Type': 'application/json'
    }
  });
} else if ('sendBeacon' in navigator) {
  // Use sendBeacon as a fallback
  navigator.sendBeacon(endpoint, data);
}

इस उदाहरण में, JSON स्ट्रिंग POST पेलोड में मिलेगी. इसे डिकोड करके, किसी ऐप्लिकेशन बैकएंड में प्रोसेस/स्टोर किया जा सकता है.

रैप कर रहा है

मेट्रिक इकट्ठा करने के बाद, यह तय करना आपकी ज़िम्मेदारी है कि उस फ़ील्ड डेटा का विश्लेषण कैसे किया जाए. फ़ील्ड डेटा का विश्लेषण करते समय, कुछ सामान्य नियमों का पालन करना ज़रूरी है. इससे यह पक्का होता है कि आपको सही नतीजे मिल रहे हैं:

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

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

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