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

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

Alex Danilo

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

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

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

हाई रिज़ॉल्यूशन में वीडियो देखने का कुल समय और now()

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

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

var myTime = window.performance.now();

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

DOMHighResTimeStamp टाइप

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

यूज़र टाइमिंग इंटरफ़ेस

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

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

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