एक वाक्य में
एक HAR फ़ाइल एक JSON-फॉर्मेट में लॉग होती है जो किसी साइट के साथ वेब ब्राउज़र के इंटरैक्शन को रिकॉर्ड करती है, जिसमें बाद में विश्लेषण के लिए हर एक नेटवर्क रिक्वेस्ट और रिस्पॉन्स को बहुत विस्तार से कैप्चर किया जाता है।
यह किस समस्या का समाधान करती है
कल्पना कीजिए: दुनिया के दूसरी तरफ बैठा एक यूज़र आपको DM करता है, "आपकी ऐप बहुत ही ज़्यादा स्लो है।" आप उसे ट्राई करते हैं। वो तो तेज़ चलती है। वे कहते हैं कि यह टूटी हुई है। आप कहते हैं कि यह मेरी मशीन पर तो ठीक काम कर रही है। बात वहीं रुक जाती है।
यह वेब डेवलपमेंट की क्लासिक "तू-तू, मैं-मैं" वाली स्थिति है। आधुनिक ब्राउज़र टूल्स से पहले, दूर बैठे यूज़र के नेटवर्क इश्यूज को डीबग करना अंदाज़े लगाने, सर्वर लॉग की गहरी छानबीन करने, और नॉन-टेक्निकल यूज़र्स से अजीब से एरर मैसेज बताने के लिए कहने जैसा एक बुरा सपना था। ब्राउज़र DevTools और उनके शानदार नेटवर्क टैब के आने के बाद भी, समस्या बनी रही: डेटा क्षणिक था। आप इसे आसानी से एक बोतल में बंद करके किसी सहकर्मी को नहीं भेज सकते थे। वॉटरफॉल चार्ट का एक स्क्रीनशॉट पूरी कहानी नहीं बताता।
और यहीं पर एंट्री होती है HTTP Archive फॉर्मेट, या HAR की। W3C के वेब परफॉर्मेंस वर्किंग ग्रुप द्वारा बनाया गया, इसे HTTP ट्रांसेक्शन को आर्काइव करने के लिए एक स्टैंडर्ड, शेयर करने योग्य फॉर्मेट के रूप में डिजाइन किया गया था। यह किसी यूज़र के ब्राउज़र में ब्लैक बॉक्स रिकॉर्डर लगाने का डिजिटल वर्शन है।
एक HAR फ़ाइल "यह मेरी मशीन पर काम करती है" वाली समस्या का समाधान करती है, क्योंकि यह किसी दिए गए वेब पेज लोड के लिए ब्राउज़र और सर्वर के बीच हुई पूरी नेटवर्क बातचीत को कैप्चर करती है। यह एक इमेज, एक स्क्रिप्ट, एक फ़ॉन्ट, या एक API कॉल के लिए हर रिक्वेस्ट को रिकॉर्ड करती है। यह भेजे गए सटीक हेडर्स, एक्सचेंज की गई कुकीज़, फॉलो किए गए रीडायरेक्ट्स, और सबसे महत्वपूर्ण, रिक्वेस्ट के हर चरण के लिए सटीक टाइमिंग को लॉग करती है।
यह सैन फ्रांसिस्को में बैठे एक डेवलपर को यह देखने की सुविधा देता है कि सिंगापुर में बैठे एक यूज़र ने बिना अंदाज़ा लगाए, मिलीसेकंड-दर-मिलीसेकंड क्या अनुभव किया। यह क्षणिक, मुश्किल से रीप्रोड्यूस होने वाले नेटवर्क बग्स को विश्लेषण योग्य बनाता है और "धीमेपन" की अस्पष्ट शिकायतों को कार्रवाई योग्य डेटा में बदल देता है।
यह अंदर से कैसे काम करती है
असल में, HAR फ़ाइल कोई जादू नहीं है। यह बस एक बड़ी, स्ट्रक्चर्ड JSON फ़ाइल है। आप इसे एक टेक्स्ट एडिटर में खोलकर सब कुछ देख सकते हैं, हालांकि एक डेडिकेटेड व्यूअर इसे समझना बेहद आसान बना देता है। चलिए अंदर झांकते हैं।
ग्रैंड स्ट्रक्चर: यह बस JSON है
एक HAR फ़ाइल में एक सिंगल टॉप-लेवल JSON ऑब्जेक्ट होता है जिसमें एक की (key) होती है: log। बाकी सब कुछ इस log ऑब्जेक्ट के अंदर रहता है।
{
"log": {
"version": "1.2",
"creator": { "name": "Chrome", "version": "118.0.0.0" },
"browser": { "name": "Chrome", "version": "118.0.0.0" },
"pages": [ /* ... one or more page objects ... */ ],
"entries": [ /* ... one or more request/response objects ... */ ]
}
}
version: HAR स्पेक वर्शन, आमतौर पर "1.2"।creator/browser: फ़ाइल बनाने वाले टूल और ब्राउज़र के बारे में मेटाडेटा। संदर्भ के लिए उपयोगी।pages: एक ऐरे जो लोड हुए मुख्य पेज या पेजों का वर्णन करती है। इसमें पेज का शीर्षक औरonLoadऔरonContentLoadजैसे हाई-लेवल इवेंट्स की टाइमिंग शामिल होती है।entries: यही शो का असली स्टार है। यह एक लंबी ऐरे है जहां हर ऑब्जेक्ट एक सिंगल नेटवर्क रिक्वेस्ट और उसके संबंधित रिस्पॉन्स को दर्शाता है।
शो का असली स्टार: entries ऐरे
जब आप एक HAR फ़ाइल का विश्लेषण करते हैं, तो आप अपना 99% समय entries में ही बिताते हैं। हर एंट्री एक रिसोर्स पर एक पूरी फाइल की तरह है।
यहाँ एक सिंगल एंट्री का सरल रूप दिया गया है:
{
"startedDateTime": "2023-10-27T10:30:05.123Z",
"time": 258.45,
"request": { /* ... details of the request ... */ },
"response": { /* ... details of the response ... */ },
"timings": { /* ... the juicy performance breakdown ... */ },
"pageref": "page_1"
}
startedDateTime: सटीक UTC टाइमस्टैम्प जब रिक्वेस्ट शुरू हुई थी।time: रिक्वेस्ट के लिए शुरू से अंत तक मिलीसेकंड में लगा कुल समय।request: एक ऑब्जेक्ट जिसमें वह सब कुछ होता है जो ब्राउज़र ने सर्वर को भेजा था।response: एक ऑब्जेक्ट जिसमें वह सब कुछ होता है जो सर्वर ने वापस भेजा था।timings: परफॉर्मेंस डीबगिंग के लिए सोने की खान। हम आगे इसका विश्लेषण करेंगे।pageref: एक ID जो इस रिक्वेस्ट को pages ऐरे में से किसी एकpageसे जोड़ती है।
रिक्वेस्ट और रिस्पॉन्स का एनाटॉमी
request और response ऑब्जेक्ट्स वही दिखाते हैं जो आप DevTools में देखते हैं।
request ऑब्जेक्ट का विवरण:
method:GET,POST,PUT, आदि।url: रिसोर्स का पूरा URL।headers: सभी रिक्वेस्ट हेडर्स की एक ऐरे, जैसेUser-Agent,Accept, औरCookie।queryString: URL पर किसी भी क्वेरी पैरामीटर की एक ऐरे।postData:POSTरिक्वेस्ट के लिए, यह पेलोड रखता है, जैसे फॉर्म डेटा या JSON बॉडी।
response ऑब्जेक्ट का विवरण:
status: HTTP स्टेटस कोड (जैसे,200,404,500)।statusText: कारण वाक्यांश (जैसे,OK,Not Found)।headers: सभी रिस्पॉन्स हेडर्स की एक ऐरे, जैसेContent-Type,Cache-Control, औरSet-Cookie।content: रिस्पॉन्स बॉडी का वर्णन करने वाला एक ऑब्जेक्ट, जिसमें इसकाsize,mimeType, और अक्सर बॉडी खुदtextप्रॉपर्टी में होती है (हालांकि इसे जगह बचाने या सुरक्षा के लिए छोड़ा जा सकता है)।
टाइमिंग्स वॉटरफॉल ब्रेकडाउन
timings ऑब्जेक्ट ही HAR व्यूअर में रंगीन वॉटरफॉल चार्ट को पावर देता है। यह कुल रिक्वेस्ट time को उसके घटक चरणों में तोड़ता है। यह पता लगाने की कुंजी है कि कोई रिक्वेस्ट 'क्यों' धीमी थी।
| टाइमिंग | इसका क्या मतलब है |
|---|---|
blocked |
रिक्वेस्ट को शुरू करने से पहले ब्राउज़र की कतार में इंतज़ार करने में बिताया गया समय। अक्सर कनेक्शन लिमिट के कारण होता है। |
dns |
DNS लुकअप पर बिताया गया समय। ज़्यादा समय धीमे DNS प्रोवाइडर का संकेत हो सकता है। |
connect |
सर्वर से TCP कनेक्शन स्थापित करने में लगने वाला समय। इसमें ssl का समय भी शामिल है। |
ssl |
(connect का हिस्सा) SSL/TLS हैंडशेक के लिए समय। ज़्यादा समय सर्वर कॉन्फिग या नेटवर्क समस्याओं की ओर इशारा कर सकता है। |
send |
सर्वर को HTTP रिक्वेस्ट भेजने में बिताया गया समय। आमतौर पर बहुत छोटा होता है। |
wait |
टाइम टू फर्स्ट बाइट (TTFB). यह सबसे महत्वपूर्ण है। रिक्वेस्ट को प्रोसेस करने और रिस्पॉन्स की पहली बाइट भेजने के लिए सर्वर का इंतज़ार करने में बिताया गया समय। एक लंबा wait समय लगभग हमेशा एक बैकएंड समस्या होती है। |
receive |
सर्वर से रिस्पॉन्स बॉडी डाउनलोड करने में बिताया गया समय। एक छोटी फ़ाइल पर लंबा receive समय एक धीमे नेटवर्क का संकेत दे सकता है; एक बड़ी फ़ाइल पर, यह अपेक्षित है। |
एक एंट्री के लिए कुल time इन व्यक्तिगत (नॉन-नेगेटिव) टाइमिंग का योग है। जब एक HAR व्यूअर आपको एक रिक्वेस्ट के लिए एक बार दिखाता है, तो यह विज़ुअली इन timings वैल्यूज को एक के बाद एक स्टैक कर रहा होता है।
असल दुनिया की कहानियाँ
रहस्यमयी धीमेपन का मामला
एक परेशान PM टीम को मैसेज करता है: "नया चेकआउट पेज हमारे सबसे बड़े क्लाइंट के लिए बहुत स्लो है! वे छोड़ने की धमकी दे रहे हैं!" डेव टीम चेकआउट फ्लो को आजमाती है। यह बिजली की तरह तेज़ है। क्लाइंट जोर देता है कि ऑर्डर कन्फर्म करने में 20 सेकंड लगते हैं। व्यर्थ की बहस के बजाय, लीड डेव क्लाइंट को HAR फ़ाइल एक्सपोर्ट करने का तरीका बताता है।
फ़ाइल खोलने पर, समस्या तुरंत स्पष्ट हो जाती है। एंट्रीज में, /api/v1/finalize_order पर POST रिक्वेस्ट का कुल time 20,145ms है। timings ऑब्जेक्ट को देखने पर, wait (TTFB) 20,000ms से अधिक है। बैकएंड सर्वर जवाब देने में 20 सेकंड ले रहा है। पता चला कि इस विशेष क्लाइंट की एक बहुत बड़ी ऑर्डर हिस्ट्री थी, और एक अनऑप्टिमाइज़्ड डेटाबेस क्वेरी केवल उनके अकाउंट के लिए टाइम आउट हो रही थी। HAR फ़ाइल ने वह पक्का सबूत प्रदान किया जिसने सीधे एक विशिष्ट बैकएंड प्रोसेस की ओर इशारा किया।
सबक: एक HAR फ़ाइल यूज़र-स्पेसिफिक कंडीशंस (जैसे अकाउंट डेटा) को कैप्चर करती है जिसे आप दोहरा नहीं सकते, जिससे एक रहस्य एक टार्गेटेड बग रिपोर्ट में बदल जाता है।
फूले हुए बंडल का अपराधी
एक मार्केटिंग साइट लाइव होती है और उसका बाउंस रेट आसमान छू रहा है। यह बस भारी महसूस होती है। एक फ्रंट-एंड डेव साइट खोलता है, DevTools खोलता है, एक सेशन रिकॉर्ड करता है, और HAR एक्सपोर्ट करता है।
HAR व्यूअर में, वे एंट्रीज को आकार के अनुसार सॉर्ट करते हैं। सबसे ऊपर main.acb123.js है, जो पूरे 5.2 MB की है। वॉटरफॉल दिखाता है कि यह एक रेंडर-ब्लॉकिंग रिसोर्स है; पेज पर कुछ भी तब तक नहीं दिखाई देता जब तक कि यह विशालकाय फ़ाइल डाउनलोड न हो जाए। receive का समय अकेले ही कई सेकंड है, यहां तक कि एक तेज़ कनेक्शन पर भी। इससे भी बदतर, इस एंट्री के response हेडर्स को देखने पर, वे देखते हैं कि सर्वर Content-Encoding: gzip हेडर नहीं भेज रहा है, बावजूद इसके कि ब्राउज़र request हेडर्स में Accept-Encoding: gzip भेज रहा था। जावास्क्रिप्ट बंडल कंप्रेस नहीं हो रहा था।
सबक: HAR फ़ाइलें बड़े आकार की एसेट्स और सर्वर की गलत कॉन्फ़िगरेशन जैसी परफॉर्मेंस किलर्स को पहचानना बेहद आसान बना देती हैं जो आपके पेज लोड टाइम की हत्या कर रही हैं।
अनंत रीडायरेक्ट लूप
एक यूज़र शिकायत करता है कि वे लॉग इन नहीं कर पा रहे हैं। वे अपनी क्रेडेंशियल दर्ज करते हैं, "लॉग इन" पर क्लिक करते हैं, और उन्हें तुरंत बिना किसी एरर के लॉगिन पेज पर वापस भेज दिया जाता है। यह एक क्लासिक लूप है। सपोर्ट यूज़र से लॉगिन प्रयास की एक HAR फ़ाइल मांगता है।
HAR में entries की सूची एक स्पष्ट कहानी बताती है:
POST /loginसफल होता है और/dashboardपर एक302 Redirectमिलता है। रिस्पॉन्स में सेशन टोकन के साथ एकSet-Cookieहेडर शामिल है।- ब्राउज़र रीडायरेक्ट का पालन करता है और एक
GET /dashboardरिक्वेस्ट करता है। - सर्वर
GET /dashboardका जवाब/loginपर302 Redirectके साथ देता है।
क्यों? डेव GET /dashboard रिक्वेस्ट एंट्री का निरीक्षण करता है। Cookie हेडर में सेशन टोकन गायब है। फिर वे शुरुआती POST /login से मिले रिस्पॉन्स की जांच करते हैं। Set-Cookie हेडर session_id=...; Secure; HttpOnly था। Secure फ्लैग का मतलब है कि ब्राउज़र कुकी केवल HTTPS पर भेजेगा। यूज़र http://staging.example.com एनवायरनमेंट पर था। ब्राउज़र सही ढंग से एक असुरक्षित कनेक्शन पर सुरक्षित कुकी भेजने से इनकार कर रहा था, इसलिए सर्वर ने उन्हें कभी भी लॉग इन के रूप में नहीं देखा।
सबक: HAR फ़ाइलें आपको HTTP रीडायरेक्ट और हेडर एक्सचेंजों का एक परफेक्ट, फ्रेम-दर-फ्रेम रीप्ले देती हैं, जिससे उन जटिल प्रमाणीकरण प्रवाहों को डीबग करना संभव हो जाता है जो चुपचाप विफल हो जाते हैं।
आम गलतियाँ और जाल
- "Preserve log" को भूल जाना। यदि आपके बग में पेज A से पेज B पर जाना शामिल है, तो आपको DevTools में "Preserve log" (या समकक्ष) विकल्प को सक्षम करना होगा। अन्यथा, नेविगेशन पर लॉग क्लियर हो जाता है, और आपकी HAR फ़ाइल में केवल पेज B के लिए रिक्वेस्ट्स होंगी।
- संवेदनशील डेटा शेयर करना। HAR फ़ाइलें बिना सोचे-समझे रिकॉर्ड करती हैं। वे API कीज, कुकीज में सेशन टोकन, और POST बॉडी में व्यक्तिगत रूप से पहचान योग्य जानकारी को कैप्चर कर लेंगी। सार्वजनिक बग ट्रैकर्स या फ़ोरम में साझा करने से पहले हमेशा HAR फ़ाइलों को सैनिटाइज़ करें।
blockedसमय की गलत व्याख्या करना। एक उच्चblockedसमय का मतलब हमेशा यह नहीं होता कि नेटवर्क व्यस्त है। ब्राउज़रों की एक सीमा होती है कि वे एक डोमेन के लिए कितने पैरेलल कनेक्शंस खोलेंगे (आमतौर पर 6)। यदि आप एक साथ 20 इमेज रिक्वेस्ट भेजते हैं, तो उनमें से 14blockedस्थिति में बैठी रहेंगी, पहले 6 में से किसी एक के समाप्त होने की प्रतीक्षा में।- कैश स्टेट को नज़रअंदाज़ करना। यदि आप फर्स्ट-लोड परफॉरमेंस का परीक्षण कर रहे हैं, तो आपको ब्राउज़र कैश को अक्षम करके रिकॉर्ड करना होगा। अन्यथा, आपको बहुत सारे
304 Not Modifiedरिस्पॉन्स या एक मिलीसेकंड से भी कम समय में पूरी होने वाली रिक्वेस्ट्स दिखाई देंगी, जो एक नए यूज़र के अनुभव को नहीं दर्शाती हैं।
यह आपके रडार पर क्यों होना चाहिए
जब भी नेटवर्क कम्युनिकेशन एक संभावित संदिग्ध हो, तो आपको HAR फ़ाइल का उपयोग करने के बारे में सोचना चाहिए।
- जब कोई यूज़र किसी परफॉर्मेंस समस्या की रिपोर्ट करता है जिसे आप रीप्रोड्यूस नहीं कर सकते।
- जब आपको एक धीमे-लोडिंग पेज को ऑप्टिमाइज़ करने की आवश्यकता हो और आप सबसे बड़े बॉटलनेक्स की पहचान करना चाहते हों।
- जब आप एक मल्टी-स्टेप API फ्लो, जैसे OAuth लॉगिन या भुगतान प्रक्रिया, को डीबग कर रहे हों और घटनाओं के सटीक क्रम को देखने की आवश्यकता हो।
- जब आपको किसी थर्ड-पार्टी सेवा (जैसे CDN या API प्रोवाइडर) के साथ बग रिपोर्ट दर्ज करने की आवश्यकता हो और आप उन्हें समस्या का अकाट्य प्रमाण प्रदान करना चाहते हों। एक HAR फ़ाइल नेटवर्क समस्याओं की सार्वभौमिक भाषा है।
और गहराई में जाएं
- HAR 1.2 Specification: मूल, वास्तविक स्पेक जो HAR फ़ाइलों की संरचना को परिभाषित करता है।
- Google Chrome DevTools: Network features reference: उस टूल के लिए एक गहन गाइड जिसका उपयोग आमतौर पर HAR फ़ाइलें बनाने के लिए किया जाता है।
- MDN Web Docs: Network request list: फ़ायरफ़ॉक्स के DevTools में नेटवर्क रिक्वेस्ट की व्याख्या पर मोज़िला का उत्कृष्ट दस्तावेज़ीकरण।
- What is a HAR File?: समस्या निवारण के लिए HAR फ़ाइलों को कैसे जेनरेट और उपयोग करें, इस पर एक अच्छा, उच्च-स्तरीय अवलोकन।