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

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

पब्लिश किया गया: 8 अक्टूबर, 2021

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

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

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

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

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

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

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

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

performance.getEntriesByType एक स्ट्रिंग स्वीकार करता है. इससे, परफ़ॉर्मेंस एंट्री बफ़र से वापस पाने के लिए, एंट्री के टाइप के बारे में पता चलता है. 'navigation' और 'resource' से, क्रमशः नेविगेशन टाइमिंग और रिसॉर्स टाइमिंग एपीआई के लिए टाइमिंग वापस मिलती हैं.

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

नेटवर्क अनुरोध की लाइफ़साइकल और टाइमिंग

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

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

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

डीएनएस लुकअप

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

  • domainLookupStart से पता चलता है कि डीएनएस लुकअप कब शुरू हुआ.
  • domainLookupEnd से पता चलता है कि डीएनएस लुकअप कब खत्म हुआ.

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

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

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

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

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

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

// 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 इंस्टेंस.
  • workerStart से पता चलता है कि सर्विस वर्कर के fetch इवेंट हैंडलर में, अनुरोध को कब हैंडल किया जाना शुरू हुआ. अगर मौजूदा पेज को कोई सर्विस वर्कर कंट्रोल नहीं कर रहा है, तो इसकी वैल्यू 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 का इस्तेमाल करना. दोनों तरीकों से, तय किए गए एंडपॉइंट पर, नॉन-ब्लॉकिंग तरीके से अनुरोध भेजा जाएगा. साथ ही, अनुरोध को इस तरह से क्यू किया जाएगा कि ज़रूरत पड़ने पर, वह मौजूदा पेज सेशन से ज़्यादा समय तक बना रहे:

// Check for navigator.sendBeacon support:
if ('sendBeacon' in navigator) {
  // 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());

  // Send the data!
  navigator.sendBeacon('/analytics', data);
}

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

नतीजा

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

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

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

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