उपयोगकर्ता समय API

अपने वेब ऐप्लिकेशन को समझना

Alex Danilo

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

आप जिस चीज़ को माप नहीं सकते उसे ऑप्टिमाइज़ नहीं कर सकते

किसी धीमे वेब ऐप्लिकेशन की स्पीड बढ़ाने के लिए पहला कदम यह तय करना है कि इसके इस्तेमाल में ज़्यादा समय कैसे लगा. JavaScript कोड के क्षेत्रों के समय प्रभाव को मापना, हॉट स्पॉट की पहचान करने का आदर्श तरीका है, जो प्रदर्शन को सुधारने का तरीका खोजने का पहला चरण है. अच्छी बात यह है कि User Timing API की मदद से JavaScript के अलग-अलग हिस्सों में एपीआई कॉल शामिल किए जा सकते हैं. साथ ही, टाइमिंग से जुड़ा पूरा डेटा निकाला जा सकता है, जिसका इस्तेमाल ऑप्टिमाइज़ करने में आपकी मदद के लिए किया जा सकता है.

हाई रिज़ॉल्यूशन वाला समय और now()

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

अपने वेब ऐप्लिकेशन का मौजूदा समय देखने के लिए, now() तरीके को कॉल करें. यह तरीका परफ़ॉर्मेंस इंटरफ़ेस का एक्सटेंशन बनाता है. नीचे दिए गए कोड में बताया गया है कि इसे कैसे किया जा सकता है:

var myTime = window.performance.now();

PerformanceTiming नाम का एक और इंटरफ़ेस है जो आपके वेब ऐप्लिकेशन के लोड होने के तरीके के बारे में कई अलग-अलग समय पर जानकारी देता है. now() वाला तरीका, PerformanceTiming में navigationStart से बीता हुआ समय दिखाता है.

DOMHighResTimeStamp का टाइप

जब आप वेब ऐप्लिकेशन को इस्तेमाल करने की कोशिश करते हैं, तो आपको Date.now() जैसी किसी चीज़ का इस्तेमाल करना चाहिए, जो DOMTimeStamp दिखाता है. DOMTimeStamp अपनी वैल्यू के तौर पर, मिलीसेकंड की पूर्णांक संख्या दिखाता है. ज़्यादा रिज़ॉल्यूशन के समय को ज़्यादा सटीक बनाने के लिए, DOMHighResTimeStamp नाम का एक नया टाइप लॉन्च किया गया. यह टाइप एक फ़्लोटिंग पॉइंट वैल्यू है, जो समय को मिलीसेकंड में भी देती है. हालांकि, यह फ़्लोटिंग पॉइंट है, इसलिए वैल्यू फ़्रैक्शनल मिलीसेकंड को दिखा सकती है. इसलिए, यह मिलीसेकंड के एक हज़ारवें हिस्से तक सटीक हो सकती है.

उपयोगकर्ता समय इंटरफ़ेस

इसलिए, अब हमारे पास हाई रिज़ॉल्यूशन वाले टाइमस्टैंप हैं. इसलिए, समय की जानकारी पाने के लिए, उपयोगकर्ता समय इंटरफ़ेस का इस्तेमाल करते हैं.

User Timing इंटरफ़ेस में ऐसे फ़ंक्शन दिए गए हैं जिनकी मदद से हम अपने ऐप्लिकेशन में अलग-अलग जगहों पर तरीकों को कॉल कर सकते हैं. इससे हैंसेल और Gretel स्टाइल का ब्रेडक्रंब ट्रेल मिल सकता है, जिससे हम ट्रैक कर सकते हैं कि समय कहां बीत रहा है.

mark() का इस्तेमाल करना

mark() वाला तरीका, हमारे टाइमिंग विश्लेषण टूलकिट में मुख्य टूल है. mark() हमारे लिए टाइम स्टैंप सेव करता है. mark() के बारे में सबसे अच्छी बात यह है कि हम टाइम स्टैम्प को नाम दे सकते हैं और एपीआई नाम और टाइम स्टैंप को एक ही यूनिट के रूप में याद रखेगा.

अपने ऐप्लिकेशन में अलग-अलग जगहों पर mark() को कॉल करके, यह पता लगाया जा सकता है कि वेब ऐप्लिकेशन में उस 'मार्क' को हिट करने में आपको कितना समय लगा.

खास जानकारी में ऐसे मार्क के लिए कई नाम सुझाए गए हैं जो दिलचस्प हो सकते हैं और जो अपने-आप में समझाए जा सकते हैं. जैसे कि mark_fully_loaded, mark_fully_visible,mark_above_the_fold वगैरह.

उदाहरण के लिए, हम नीचे दिए गए कोड का इस्तेमाल करके, ऐप्लिकेशन के पूरी तरह लोड होने के लिए निशान सेट कर सकते हैं:

window.performance.mark('mark_fully_loaded');

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

measure() की मदद से मेज़रमेंट की गिनती की जा रही है

कई टाइमिंग मार्क सेट कर लेने के बाद, आपको उनके बीच बिताए गए समय का पता लगाना होगा. इसके लिए, measure() तरीके का इस्तेमाल किया जाता है.

measure() तरीका मार्क के बीच बिताए गए समय का हिसाब लगाता है. साथ ही, यह PerformanceTiming इंटरफ़ेस में आपके मार्क और किसी जाने-माने इवेंट के नाम के बीच के समय को माप सकता है.

उदाहरण के लिए, नीचे दिए गए कोड का इस्तेमाल करके, डीओएम के पूरा होने से लेकर आपके ऐप्लिकेशन की स्थिति के पूरी तरह लोड होने तक का समय निकाला जा सकता है:

window.performance.measure('measure_load_from_dom', 'domComplete', 'mark_fully_loaded');

जब आप measure() को कॉल करते हैं, तो यह नतीजे को आपके सेट किए गए मार्क से अलग सेव करता है, ताकि आप उन्हें बाद में फिर से पा सकें. जब आपका ऐप्लिकेशन चलता है, तो ऐप्लिकेशन के बंद होने का समय सेव करने से, यह ऐप्लिकेशन रिस्पॉन्सिव बना रहता है. साथ ही, आपके ऐप्लिकेशन के कुछ काम खत्म हो जाने के बाद भी सारा डेटा हटाया जा सकता है, ताकि बाद में उसका विश्लेषण किया जा सके.

clearMarks() वाले खारिज किए गए निशान

कभी-कभी अपने सेट अप किए हुए कई निशानों से छुटकारा पाना मददगार होता है. उदाहरण के लिए, हो सकता है कि आप अपने वेब ऐप्लिकेशन पर बैच रन करते हों और इसलिए हर बार को नए सिरे से शुरू करना चाहें.

clearMarks() पर कॉल करके, आपने जो भी निशान सेट अप किए हैं उन्हें हटाना आसान है.

इसलिए, नीचे दिया गया उदाहरण आपके सभी मौजूदा मार्क को खारिज कर देगा, ताकि अगर आप चाहें, तो फिर से टाइमिंग को सेट अप कर सकें.

window.performance.clearMarks();

बेशक, कुछ मामलों में हो सकता है कि आप अपने सभी मार्क न हटाना चाहें. इसलिए अगर आप खास निशानों से छुटकारा पाना चाहते हैं, तो आप बस उस मार्क का नाम पास कर दें जिसे आप हटाना चाहते हैं. उदाहरण के लिए, नीचे दिया गया कोड:

window.peformance.clearMarks('mark_fully_loaded');

पहले उदाहरण में सेट किए गए अपने निशान से छुटकारा दिलाता है, जबकि ऐसे अन्य मार्क को छोड़ देता है जिन्हें हम बिना बदलाव के सेट करते हैं.

आपने जो उपाय किए हैं, हो सकता है कि आप उन्हें हटाना चाहें. ऐसा करने का एक तरीका भी है जिसे clearMeasures() कहते हैं. यह clearMarks() की तरह ही काम करती है. इसके बजाय, यह आपके बनाए गए किसी भी माप पर काम करती है. उदाहरण के लिए, कोड:

window.performance.clearMeasures('measure_load_from_dom');

ऊपर दिए गए measure() उदाहरण में हमारी बनाई गई माप को हटा देगा. अगर आपको सभी मेज़र हटाने हैं, तो यह clearMarks() की तरह ही काम करता है. इसमें सिर्फ़ clearMeasures() को बिना आर्ग्युमेंट के कॉल किया जाता है.

समय से जुड़ा डेटा बाहर निकाला जा रहा है

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

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

नीचे दिया गया कोड:

var items = window.performance.getEntriesByType('mark');

यह फ़ंक्शन, हमें उन सभी मार्क की सूची दिखाता है जिन्हें हमारे वेब ऐप्लिकेशन में हिट किया गया है. साथ ही, इसमें कोड भी शामिल है:

var items = window.performance.getEntriesByType('measure');

हमें उन सभी उपायों की सूची मिलती है जो हमने खुद किए हैं.

आपके पास दिए गए खास नाम का इस्तेमाल करके, एंट्री की सूची को वापस पाने का विकल्प भी होता है. उदाहरण के लिए, कोड:

var items = window.performance.getEntriesByName('mark_fully_loaded');

हमें एक सूची दिखेगी, जिसमें एक आइटम होगा. इस सूची में startTime प्रॉपर्टी में मौजूद, ‘mark_full_loaded’ टाइम स्टैंप है.

XHR अनुरोध का समय (उदाहरण)

हमारे पास User Timing API के बारे में पूरी जानकारी है, इसलिए हम इसका इस्तेमाल करके यह विश्लेषण कर सकते हैं कि हमारे वेब ऐप्लिकेशन में हमारे सभी XMLHttpRequests को कितना समय लगता है.

सबसे पहले हम एक फ़ंक्शन कॉल जारी करने के लिए अपने सभी send() अनुरोधों में बदलाव करेंगे, जो मार्क सेट अप करते हैं. साथ ही, हम अपने सक्सेस कॉलबैक को, एक फ़ंक्शन कॉल से बदलेंगे जो एक और निशान सेट करता है. इसके बाद, अनुरोध में लगने वाले समय का आकलन जनरेट करता है.

इसलिए आम तौर पर हमारा XMLHttpRequest कुछ ऐसा दिखेगा:

var myReq = new XMLHttpRequest();
myReq.open('GET', url, true);
myReq.onload = function(e) {
  do_something(e.responseText);
}
myReq.send();

अपने उदाहरण में हम अनुरोधों की संख्या को ट्रैक करने के लिए एक ग्लोबल काउंटर जोड़ेंगे. साथ ही, हम हर अनुरोध को सेव करने के लिए, उसका इस्तेमाल करेंगे. ऐसा करने के लिए कोड, ऐसा दिखेगा:

var reqCnt = 0;

var myReq = new XMLHttpRequest();
myReq.open('GET', url, true);
myReq.onload = function(e) {
  window.performance.mark('mark_end_xhr');
  reqCnt++;
  window.performance.measure('measure_xhr_' + reqCnt, 'mark_start_xhr', 'mark_end_xhr');
  do_something(e.responseText);
}
window.performance.mark('mark_start_xhr');
myReq.send();

ऊपर दिया गया कोड हमारे भेजे गए हर XMLHttpRequest के लिए, एक यूनीक नाम वाली वैल्यू के साथ एक माप जनरेट करता है. हम यह मान रहे हैं कि अनुरोध क्रम में चलाए जाते हैं - साथ-साथ लोड होने वाले अनुरोधों को हैंडल करने के लिए, साथ-साथ लोड होने वाले अनुरोधों के कोड को थोड़ा ज़्यादा मुश्किल होना चाहिए. इसलिए, हम इसे पाठक के लिए सिर्फ़ एक कसरत के तौर पर छोड़ देंगे.

जब वेब ऐप्लिकेशन कई अनुरोधों को पूरा कर लेता है, तब हम उन सभी को नीचे दिए गए कोड का इस्तेमाल करके कंसोल में डाल सकते हैं:

var items = window.performance.getEntriesByType('measure');
for (var i = 0; i < items.length; ++i) {
  var req = items[i];
  console.log('XHR ' + req.name + ' took ' + req.duration + 'ms');
}

नतीजा

User समय API से आपको अपने वेब ऐप्लिकेशन के किसी भी पहलू में लागू करने के लिए कई बेहतरीन टूल मिलते हैं. अपने ऐप्लिकेशन के हॉटस्पॉट को सीमित करने के लिए, आपको अपने वेब ऐप्लिकेशन में एपीआई कॉल अलग-अलग करने होंगे. साथ ही, आपको जनरेट किए गए टाइमिंग डेटा को पोस्ट-प्रोसेस करके, यह साफ़ तौर पर बताना होगा कि आपके ऐप्लिकेशन में इस्तेमाल कहां किया जा रहा है. अगर आपका ब्राउज़र इस एपीआई के साथ काम नहीं करता है, तो क्या होगा? कोई बात नहीं, आपको यहां एक बेहतरीन पॉलीफ़िल मिल सकता है, जो एपीआई को अच्छी तरह एम्युलेट करता है. साथ ही, webpagetest.org के साथ अच्छी तरह से काम करता है. तो फिर इंतज़ार कैसा? अपने ऐप्लिकेशन पर User Timing API का अभी इस्तेमाल करें, आपको उनकी रफ़्तार बढ़ाने का तरीका पता चलेगा और आपके उपयोगकर्ता उनके अनुभव को बेहतर बनाने के लिए आपको धन्यवाद देंगे.