एचटीटीपी कैश की मदद से ग़ैर-ज़रूरी नेटवर्क अनुरोधों को रोकें

नेटवर्क पर संसाधनों को फ़ेच करने की प्रोसेस धीमी और महंगी, दोनों होती है:

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

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

यह गाइड आपको एचटीटीपी कैशिंग को लागू करने से जुड़ी बुनियादी जानकारी देती है.

वेबसाइट का अलग-अलग ब्राउज़र पर चलना

असल में, एचटीटीपी कैश नाम का कोई एक एपीआई नहीं है. यह वेब प्लैटफ़ॉर्म एपीआई के कलेक्शन का सामान्य नाम है. ये एपीआई सभी ब्राउज़र पर काम करते हैं:

एचटीटीपी कैश कैसे काम करता है

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

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

कॉन्सेप्ट के बारे में खास जानकारी पाने के लिए, एमडीएन का एचटीटीपी कैशिंग लेख पढ़ें.

अनुरोध के हेडर: डिफ़ॉल्ट सेटिंग पर बने रहें (आम तौर पर)

वेब ऐप्लिकेशन के आउटगोइंग अनुरोधों में कई अहम हेडर शामिल किए जाने चाहिए. हालांकि, अनुरोध करते समय, ब्राउज़र अक्सर इन्हें आपकी ओर से सेट करता है. रीफ़्रेश करने की जांच पर असर डालने वाले अनुरोध हेडर, जैसे कि If-None-Match और If-Modified-Since सिर्फ़ तब दिखते हैं, जब ब्राउज़र एचटीटीपी कैश में मौजूदा वैल्यू को ठीक से समझ लेता है.

यह अच्छी खबर है—इसका मतलब है कि आप अपने एचटीएमएल में <img src="my-image.png"> जैसे टैग शामिल करना जारी रख सकते हैं. साथ ही, ब्राउज़र अपने-आप एचटीटीपी कैश मेमोरी का काम करता है और आपको ज़्यादा मेहनत नहीं करनी पड़ती.

रिस्पॉन्स हेडर: अपना वेब सर्वर कॉन्फ़िगर करें

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

  • Cache-Control. सर्वर यह बताने के लिए Cache-Control निर्देश दे सकता है कि ब्राउज़र और दूसरे इंटरमीडिएट कैश को, किसी एक रिस्पॉन्स को कैसे और कब तक कैश मेमोरी में सेव करना चाहिए.
  • ETag. अगर ब्राउज़र को कैश मेमोरी में सेव किया गया ऐसा रिस्पॉन्स मिलता है जिसकी समयसीमा खत्म हो चुकी है, तो वह सर्वर को एक छोटा टोकन (आम तौर पर, फ़ाइल के कॉन्टेंट का हैश) भेज सकता है. इससे यह देखा जा सकता है कि फ़ाइल बदली गई है या नहीं. अगर सर्वर उसी टोकन का इस्तेमाल करता है, तो फ़ाइल पहले जैसी ही रहेगी और उसे फिर से डाउनलोड करने की ज़रूरत नहीं होगी.
  • Last-Modified. यह हेडर ETag की तरह ही काम करता है. हालांकि, ETag की कॉन्टेंट के आधार पर बनी रणनीति के उलट, यह तय करने के लिए कि संसाधन में बदलाव हुआ है या नहीं, समय के हिसाब से रणनीति का इस्तेमाल किया जाता है.

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

आपकी कुछ खोज से बचने के लिए, यहां कुछ लोकप्रिय वेब सर्वर कॉन्फ़िगर करने के निर्देश दिए गए हैं:

Cache-Control रिस्पॉन्स हेडर को छोड़ने पर, एचटीटीपी कैश मेमोरी में सेव करने की सुविधा बंद नहीं होती! इसके बजाय, ब्राउज़र असरदार तरीके से यह अनुमान लगाते हैं कि किसी खास तरह के कॉन्टेंट के लिए, कैश मेमोरी में सेव करने का कौनसा तरीका सबसे बेहतर रहेगा. हो सकता है कि आपको उस ऑफ़र के मुकाबले ज़्यादा कंट्रोल चाहिए हो. इसलिए, समय निकालकर अपने रिस्पॉन्स हेडर को कॉन्फ़िगर करें.

आपको किन रिस्पॉन्स हेडर की वैल्यू का इस्तेमाल करना चाहिए?

अपने वेब सर्वर के रिस्पॉन्स हेडर कॉन्फ़िगर करते समय आपको इन दो स्थितियों पर ध्यान देना चाहिए.

वर्शन वाले यूआरएल को लंबे समय तक कैश मेमोरी में सेव करना

वर्शन वाले यूआरएल, कैश मेमोरी में सेव करने की आपकी रणनीति में कैसे मदद कर सकते हैं
वर्शन वाले यूआरएल का इस्तेमाल करना सबसे सही होता है, क्योंकि इससे कैश मेमोरी में सेव किए गए जवाबों को आसानी से अमान्य किया जा सकता है.

मान लें कि आपका सर्वर, ब्राउज़र को किसी सीएसएस फ़ाइल को एक साल (Cache-Control: max-age=31536000) के लिए कैश मेमोरी में सेव करने का निर्देश देता है. हालांकि, आपके डिज़ाइनर ने अभी-अभी एक आपातकालीन अपडेट किया है. आपको इसे तुरंत रोल आउट करना होगा. कैश मेमोरी में सेव की गई "पुरानी" कॉपी को अपडेट करने के लिए, ब्राउज़र को सूचना कैसे दी जाती है? ऐसा नहीं किया जा सकता, कम से कम रिसॉर्स के यूआरएल को बदले बिना ऐसा नहीं किया जा सकता. ब्राउज़र, रिस्पॉन्स को कैश मेमोरी में सेव करता है. इसके बाद, कैश मेमोरी में सेव किए गए वर्शन का इस्तेमाल तब तक किया जाता है, जब तक कि वह अपडेट न हो जाए. यह तब तक इस्तेमाल किया जाता है, जब तक कि वह max-age या expires के हिसाब से नया न हो. इसके अलावा, किसी दूसरी वजह से उसे कैश मेमोरी से हटाए जाने तक भी इस्तेमाल किया जाता है. उदाहरण के लिए, उपयोगकर्ता की कैश मेमोरी मिटानी. इस वजह से, पेज बनाते समय अलग-अलग उपयोगकर्ता फ़ाइल के अलग-अलग वर्शन इस्तेमाल कर सकते हैं: जिन उपयोगकर्ताओं ने अभी-अभी संसाधन को फ़ेच किया है वे नए वर्शन का इस्तेमाल करते हैं. वहीं, जिन उपयोगकर्ताओं ने पुरानी (लेकिन अब भी मान्य) कॉपी को कैश मेमोरी में सेव किया है वे पेज के रिस्पॉन्स के पुराने वर्शन का इस्तेमाल करते हैं. आपको इन दोनों तरीकों का ज़्यादा से ज़्यादा फ़ायदा कैसे मिल सकता है: क्लाइंट-साइड कैश मेमोरी और तुरंत अपडेट पाने की सुविधा? आप संसाधन का यूआरएल बदल देते हैं और उपयोगकर्ता के कॉन्टेंट में बदलाव होने पर, उसे नया जवाब डाउनलोड करने के लिए मजबूर करते हैं. आम तौर पर, ऐसा करने के लिए फ़ाइल के नाम में उसका फ़िंगरप्रिंट या वर्शन नंबर एम्बेड किया जाता है. उदाहरण के लिए, style.x234dff.css.

ऐसे यूआरएल के अनुरोधों का जवाब देते समय जिनमें "फ़िंगरप्रिंट" या वर्शन की जानकारी है और जिनके कॉन्टेंट में कभी बदलाव नहीं किया जाना चाहिए. अपने जवाबों में Cache-Control: max-age=31536000 जोड़ें.

इस वैल्यू को सेट करने से, ब्राउज़र को पता चलता है कि जब उसे अगले एक साल (31,536,000 सेकंड; ज़्यादा से ज़्यादा वैल्यू) में किसी भी समय वही यूआरएल लोड करने की ज़रूरत होगी, तो वह एचटीटीपी कैश में मौजूद वैल्यू का तुरंत इस्तेमाल कर सकता है. इसके लिए, उसे आपके वेब सर्वर से नेटवर्क अनुरोध करने की ज़रूरत नहीं पड़ेगी. बहुत बढ़िया—आपने तुरंत ही भरोसा और स्पीड हासिल कर ली है.

वेबपैक जैसे बिल्ड टूल आपकी एसेट के यूआरएल में हैश फ़िंगरप्रिंट असाइन करने की प्रोसेस अपने-आप में बदल सकते हैं.

बिना वर्शन वाले यूआरएल के लिए सर्वर की फिर से पुष्टि

माफ़ करें, आपके लोड किए गए सभी यूआरएल के वर्शन नहीं हैं. हो सकता है कि अपने वेब ऐप्लिकेशन को डिप्लॉय करने से पहले, बिल्ड स्टेप शामिल न किया जा सके. इसलिए, अपने एसेट यूआरएल में हैश नहीं जोड़ा जा सकता. हर वेब ऐप्लिकेशन को एचटीएमएल फ़ाइलों की ज़रूरत होती है. उन फ़ाइलों के वर्शन की जानकारी कभी शामिल नहीं होती, क्योंकि अगर उन्हें यह याद रखना है कि https://example.com/index.34def12.html यूआरएल है, तो कोई आपके वेब ऐप्लिकेशन का इस्तेमाल नहीं कर पाएगा. तो उन यूआरएल के लिए क्या किया जा सकता है?

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

यहां दिए गए Cache-Control वैल्यू की मदद से, यह बेहतर बनाया जा सकता है कि वर्शन से बाहर रखे गए यूआरएल को कैश मेमोरी में कहां और कैसे कैश मेमोरी में सेव किया जाता है:

  • no-cache. यह ब्राउज़र को निर्देश देता है कि कैश मेमोरी में सेव किए गए यूआरएल के वर्शन का इस्तेमाल करने से पहले, ब्राउज़र को हर बार सर्वर की मदद से दोबारा पुष्टि करनी होगी.
  • no-store. यह ब्राउज़र और बीच में मौजूद कैश मेमोरी (जैसे कि सीडीएन) को फ़ाइल के किसी भी वर्शन को सेव न करने का निर्देश देता है.
  • private. ब्राउज़र, फ़ाइल को कैश मेमोरी में सेव कर सकते हैं, लेकिन बीच के लेवल पर कैश मेमोरी में सेव नहीं कर सकते.
  • public. रिस्पॉन्स को किसी भी कैश मेमोरी से सेव किया जा सकता है.

इस्तेमाल की जाने वाली Cache-Control वैल्यू तय करने की प्रोसेस को विज़ुअलाइज़ करने के लिए, अपेंडिक्स: Cache-Control फ़्लोचार्ट देखें. यह भी ध्यान रखें कि Cache-Control, डायरेक्टिव की कॉमा-सेपरेटेड लिस्ट स्वीकार कर सकता है. अपेंडिक्स: Cache-Control उदाहरण देखें.

साथ ही, दो अतिरिक्त रिस्पॉन्स हेडर में से कोई एक सेट करने से भी मदद मिल सकती है: ETag या Last-Modified. जैसा कि रिस्पॉन्स हेडर में बताया गया है, ETag और Last-Modified दोनों का मकसद एक ही है: यह तय करना कि ब्राउज़र को ऐसी कैश फ़ाइल को फिर से डाउनलोड करने की ज़रूरत है या नहीं जिसकी समयसीमा खत्म हो चुकी है. हम ETag का इस्तेमाल करने का सुझाव देते हैं, क्योंकि यह ज़्यादा सटीक है.

ETag का उदाहरण

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

ETag या Last-Modified को सेट करने पर, फिर से पुष्टि करने के अनुरोध को और बेहतर बनाया जा सकता है. इनसे If-Modified-Since या If-None-Match अनुरोध के हेडर ट्रिगर हो जाते हैं, जिनका ज़िक्र अनुरोध हेडर में किया गया है.

जब सही तरीके से कॉन्फ़िगर किया गया वेब सर्वर उन इनकमिंग अनुरोध हेडर को देखता है, तो वह इस बात की पुष्टि कर सकता है कि ब्राउज़र के एचटीटीपी कैश में पहले से मौजूद संसाधन का वर्शन, वेब सर्वर पर सबसे नए वर्शन से मेल खाता है या नहीं. अगर कोई क्वेरी मैच होती है, तो सर्वर 304 Not Modified एचटीटीपी रिस्पॉन्स के साथ जवाब दे सकता है. यह रिस्पॉन्स, "Ok, पहले से उपलब्ध टेस्टिंग का इस्तेमाल करते रहें!" इस तरह का जवाब भेजते समय, ट्रांसफ़र करने के लिए बहुत कम डेटा होता है. इसलिए, अनुरोध किए जा रहे असल संसाधन की कॉपी को वापस भेजने के मुकाबले, यह प्रोसेस ज़्यादा तेज़ होती है.

एक क्लाइंट का डायग्राम, जिसमें संसाधन का अनुरोध किया जा रहा है और सर्वर 304 हेडर के साथ जवाब दे रहा है.
ब्राउज़र, सर्वर से /file का अनुरोध करता है. साथ ही, इसमें If-None-Match हेडर भी शामिल करता है, ताकि सर्वर को पूरी फ़ाइल सिर्फ़ तब दिखे, जब सर्वर पर मौजूद फ़ाइल का ETag, ब्राउज़र की If-None-Match वैल्यू से मेल न खाता हो. इस मामले में, दोनों वैल्यू मैच करती हैं. इसलिए, सर्वर रिस्पॉन्स के साथ 304 Not Modified रिस्पॉन्स भेजता है. साथ ही, यह निर्देश देता है कि फ़ाइल को कितनी देर तक कैश मेमोरी में रखना चाहिए (Cache-Control: max-age=120).

खास जानकारी

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

ये Cache-Control कॉन्फ़िगरेशन अच्छी शुरुआत के लिए हैं:

  • उन रिसॉर्स के लिए Cache-Control: no-cache जिन्हें हर बार इस्तेमाल करने से पहले, सर्वर की मदद से दोबारा पुष्टि की जानी चाहिए.
  • Cache-Control: no-store में ऐसे रिसॉर्स मिलेंगे जिन्हें कभी कैश मेमोरी में सेव नहीं किया जाना चाहिए.
  • वर्शन वाले संसाधनों के लिए Cache-Control: max-age=31536000.

इसके अलावा, ETag या Last-Modified हेडर की मदद से, कैश मेमोरी के उन संसाधनों की बेहतर तरीके से पुष्टि की जा सकती है जिनकी समयसीमा खत्म हो चुकी है.

ज़्यादा जानें

अगर आपको Cache-Control हेडर का इस्तेमाल करने से जुड़ी बुनियादी बातों के बारे में जानना है, तो जेक आर्चिबाल्ड की कैशिंग के सबसे सही तरीके और ज़्यादा से ज़्यादा उम्र की जानकारी वाली गाइड देखें.

वेबसाइट पर वापस आने वाले लोगों के लिए, कैश मेमोरी के इस्तेमाल को ऑप्टिमाइज़ करने के बारे में जानकारी पाने के लिए, कैश मेमोरी में सेव किया गया डेटा देखें.

अपेंडिक्स: अन्य सलाह

अगर आपके पास ज़्यादा समय है, तो यहां कुछ ऐसे तरीके दिए गए हैं जिनसे एचटीटीपी कैश के इस्तेमाल को ऑप्टिमाइज़ किया जा सकता है:

  • एक जैसे यूआरएल का इस्तेमाल करें. अगर एक ही कॉन्टेंट को अलग-अलग यूआरएल पर इस्तेमाल किया जाता है, तो वह कॉन्टेंट कई बार फ़ेच और सेव किया जाएगा.
  • चर्न आउट कम करें. अगर किसी संसाधन (जैसे कि सीएसएस फ़ाइल) का कुछ हिस्सा अक्सर अपडेट होता है, जबकि फ़ाइल का बाकी हिस्सा (जैसे कि लाइब्रेरी कोड) अपडेट नहीं होता है, तो अक्सर अपडेट होने वाले कोड को एक अलग फ़ाइल में बांटें. साथ ही, बार-बार अपडेट होने वाले कोड के लिए कम अवधि की कैश मेमोरी की रणनीति और ऐसे कोड के लिए कैश मेमोरी की अवधि वाली लंबी रणनीति का इस्तेमाल करें जो अक्सर नहीं बदलता.
  • अगर Cache-Control नीति में कुछ हद तक पुरानी जानकारी स्वीकार की जाती है, तो नया stale-while-revalidate डायरेक्टिव देखें.

अपेंडिक्स: Cache-Control फ़्लोचार्ट

फ़्लोचार्ट

अपेंडिक्स: Cache-Control के उदाहरण

Cache-Control की कीमत का जानकारी
max-age=86400 रिस्पॉन्स को ब्राउज़र और बीच के कैश मेमोरी में, एक दिन (60 सेकंड x 60 मिनट x 24 घंटे) तक कैश मेमोरी में सेव किया जा सकता है.
private, max-age=600 ब्राउज़र, रिस्पॉन्स को 10 मिनट (60 सेकंड x 10 मिनट) तक कैश मेमोरी में सेव कर सकता है. हालांकि, इस कैश मेमोरी को बीच में मौजूद कैश मेमोरी में नहीं रखा जा सकता.
public, max-age=31536000 जवाब को किसी भी कैश मेमोरी के ज़रिए एक साल तक सेव किया जा सकता है.
no-store रिस्पॉन्स को कैश मेमोरी में सेव करने की अनुमति नहीं होती. हर अनुरोध पर, रिस्पॉन्स को पूरा फ़ेच करना ज़रूरी होता है.