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

नेटवर्क पर संसाधन फ़ेच करने में ज़्यादा समय भी लगता है. साथ ही, यह तरीका महंगा भी है:

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

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

इस गाइड में, एचटीटीपी कैश मेमोरी में डेटा सेव करने की सुविधा को लागू करने की बुनियादी बातें बताई गई हैं.

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

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

Cache-Control

ब्राउज़र सहायता

  • सही
  • 12
  • सही
  • सही

सोर्स

ETag

ब्राउज़र सहायता

  • सही
  • 12
  • सही
  • सही

सोर्स

Last-Modified

ब्राउज़र सहायता

  • सही
  • 12
  • सही
  • सही

सोर्स

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

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

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

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

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

आपके वेब ऐप्लिकेशन के आउटगोइंग अनुरोधों में कई अहम हेडर शामिल किए जाने चाहिए. हालांकि, जब अनुरोध करता है, तो ब्राउज़र करीब-करीब हमेशा आपकी ओर से उन्हें सेट करने का ध्यान रखता है. अनुरोध के हेडर, जैसे कि If-None-Match और If-Modified-Since जैसे अनुरोध हेडर, एचटीटीपी कैश में मौजूद मौजूदा वैल्यू के बारे में ब्राउज़र की समझ के आधार पर दिखते हैं. जैसे, 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 सेकंड; अधिकतम समर्थित मान) में किसी भी समय समान URL लोड करने की आवश्यकता हो, तो वह आपके वेब सर्वर पर नेटवर्क अनुरोध किए बिना तुरंत HTTP कैश में मान का उपयोग कर सकता है. बहुत बढ़िया—आपने नेटवर्क से बचने की वजह से तुरंत विश्वसनीयता और रफ़्तार हासिल कर ली है!

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

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

माफ़ करें, आप जो यूआरएल लोड करते हैं सभी यूआरएल के अलग-अलग वर्शन नहीं होते. शायद आप अपने वेब ऐप्लिकेशन को डिप्लॉय करने से पहले, बिल्ड स्टेप शामिल न कर पाएं. इसलिए, अपने ऐसेट यूआरएल में हैश नहीं जोड़े जा सकते. साथ ही, हर वेब ऐप्लिकेशन में एचटीएमएल फ़ाइलों की ज़रूरत होती है—उन फ़ाइलों में (करीब!) वर्शनिंग की जानकारी कभी शामिल नहीं होती, क्योंकि कोई भी व्यक्ति आपके वेब ऐप्लिकेशन का इस्तेमाल नहीं करेगा, ताकि उसे याद रहे कि विज़िट किया जाने वाला यूआरएल 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 HTTP जवाब के साथ जवाब दे सकता है, जो "Hey, आपको जो पहले से मौजूद है उसका इस्तेमाल करते रहें!" इस तरह का जवाब भेजने के दौरान, ट्रांसफ़र करने के लिए बहुत कम डेटा होता है. इसलिए, अनुरोध किए गए असल संसाधन की कॉपी को वापस भेजने की तुलना में यह आम तौर पर ज़्यादा तेज़ होता है.

संसाधन का अनुरोध करने वाले क्लाइंट और 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 उदाहरण

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