कैश मेमोरी में सेव करें ❤️

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

यह पोस्ट, कैश मेमोरी में सेव किया गया कॉन्टेंट बनाने वाले वीडियो की साथी है. यह 'Chrome डेवलपर समिट 2020' में एक्सटेंडेड कॉन्टेंट का हिस्सा है. इन लिंक पर दिए गए वीडियो को ज़रूर देखें:

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

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

लक्ष्य

जब कोई साइट दूसरी बार लोड होती है, तो आपके दो लक्ष्य होते हैं:

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

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

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

बैकग्राउंड

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

इंटरनेट पर नियमित तौर पर आने वाले लोगों के पास उतनी सुविधाएं नहीं होती जितनी चाहिए. इसलिए, यह पक्का करना हमारे लिए ज़रूरी है कि हमारे उपयोगकर्ता दूसरी बार लोड होने में समय बर्बाद न करें. साथ ही, यह पक्का करना भी ज़रूरी है कि वे इस काम में परेशान न हों. (अगर आपको जानना है कि web.dev/live साइट कैसे बंद हो गई, तो यह वीडियो देखें!)

बुनियादी जानकारी की वजह से, "पुरानी कैश मेमोरी" होने की एक आम वजह है, कैश मेमोरी में 1999 का डिफ़ॉल्ट दस्तावेज़ बनाना. यह Last-Modified हेडर पर निर्भर करता है:

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

आपकी लोड की गई हर फ़ाइल को उसके मौजूदा लाइफ़टाइम के 10% ज़्यादा समय तक रखा जाता है, जैसा कि आपका ब्राउज़र देखता है. उदाहरण के लिए, अगर index.html को एक महीने पहले बनाया गया था, तो आपका ब्राउज़र इसे और तीन दिनों तक कैश मेमोरी में रखेगा.

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

रोशनी से जगमगाता रास्ता

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

अपने वेब होस्ट को इस हेडर की मदद से वेब अनुरोधों का जवाब देने के लिए कॉन्फ़िगर किया जा सकता है:

Cache-Control: max-age=0,must-revalidate,public

इसका मतलब है कि फ़ाइल किसी भी समय के लिए मान्य नहीं है. साथ ही, इसे फिर से इस्तेमाल करने से पहले, आपको नेटवर्क से इसकी पुष्टि करनी होगी. ऐसा न करने पर, इसे सिर्फ़ "सुझाया गया" ही माना जाएगा.

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

हालांकि, यह एक मॉडर्न तरीका है जो किसी लोकप्रिय सीडीएन, Netlify पर डिफ़ॉल्ट रूप से होता है, लेकिन इसे करीब-करीब किसी भी सीडीएन पर कॉन्फ़िगर किया जा सकता है. Firebase होस्टिंग के लिए, अपनी firebase.json फ़ाइल के होस्टिंग सेक्शन में इस हेडर को शामिल किया जा सकता है:

"headers": [
  // Be sure to put this last, to not override other headers
  {
    "source": "**",
    "headers": [ {
      "key": "Cache-Control",
      "value": "max-age=0,must-revalidate,public"
    }
  }
]

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

फ़िंगरप्रिंट वाले यूआरएल

अपनी साइट पर दिखाई जाने वाली एसेट, इमेज वगैरह के नाम में फ़ाइल के कॉन्टेंट का हैश शामिल करके, आप यह पक्का कर सकते हैं कि इन फ़ाइलों में हमेशा यूनीक कॉन्टेंट हो. इस तरह, उदाहरण के लिए sitecode.af12de.js नाम की फ़ाइलें बनेंगी. जब आपका सर्वर इन फ़ाइलों के अनुरोधों का जवाब देता है, तो आप अपने असली उपयोगकर्ता के ब्राउज़र को इस हेडर के साथ कॉन्फ़िगर करके सुरक्षित रूप से उन्हें लंबे समय तक कैश मेमोरी में सेव करने का निर्देश दे सकते हैं:

Cache-Control: max-age=31536000,immutable

यह वैल्यू, साल की जानकारी होती है. इसे सेकंड में दिखाया जाता है. और स्पेसिफ़िकेशन के मुताबिक, यह "हमेशा" के बराबर है.

खास बात यह है कि ये हैश खुद जनरेट न करें—यह बहुत ज़्यादा मैन्युअल काम है! इसमें मदद करने के लिए, Webpack, Rollup वगैरह जैसे टूल का इस्तेमाल किया जा सकता है. इनके बारे में ज़्यादा जानने के लिए, टूलिंग रिपोर्ट पढ़ें.

याद रखें कि फ़िंगरप्रिंट वाले यूआरएल से सिर्फ़ JavaScript को फ़ायदा नहीं मिल सकता. इसके अलावा, आइकॉन, सीएसएस, और नहीं बदली जा सकने वाली अन्य डेटा फ़ाइलों जैसी ऐसेट को भी इस तरह नाम दिया जा सकता है. (और कोड स्प्लिट के बारे में और जानने के लिए ऊपर दिया गया वीडियो देखना न भूलें. इससे आपकी साइट के बदलने पर कम कोड भेजा जा सकता है.)

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

हम लोगों के लिए उपलब्ध पेजों का नाम इस तरह नहीं बदल सकते कि उन्हें देखने के लिए, आसानी से इस्तेमाल होने वाले पेज हों: index.html फ़ाइल का नाम बदलकर index.abcd12.html करना. यह बिलकुल संभव नहीं है. उपयोगकर्ताओं के हर बार आपकी साइट लोड करने पर, नए यूआरएल पर जाने को कहा नहीं जा सकता! इन 'फ़्रेंडली' यूआरएल का नाम बदला नहीं जा सकता और न ही कैश मेमोरी में इस तरह सेव किया जा सकता है, जिससे मैं एक बीच की तरफ़ बढ़ जाता हूँ.

बीच का मैदान

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

अगर आपको इन "फ़्रेंडली" यूआरएल और उनके एचटीएमएल को कैश मेमोरी में सेव करना है, तो यह देखना ज़रूरी है कि इनमें कौन-कौनसी डिपेंडेंसी शामिल हैं, उन्हें किस तरह कैश मेमोरी में सेव किया जा सकता है, और उनके यूआरएल को कुछ समय के लिए कैश मेमोरी में सेव करने से आप पर क्या असर पड़ सकता है. आइए एक ऐसा एचटीएमएल पेज देखें जिसमें इस तरह की इमेज शामिल हो:

<img src="/images/foo.jpeg" loading="lazy" />

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

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

आम तौर पर, कैश मेमोरी में डेटा सेव करने की सुविधा से जुड़ी ज़्यादातर गाइड, इस तरह की सेटिंग के बारे में बताती हैं. क्या आपको डेटा को एक घंटे या कई घंटों के लिए कैश मेमोरी में सेव करना है. इस तरह की कैश मेमोरी सेट करने के लिए, इस तरह के हेडर का इस्तेमाल करें (जो 3, 600 सेकंड या एक घंटे के लिए कैश मेमोरी में सेव होता है):

Cache-Control: max-age=3600,immutable,public

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

बिना एचटीएमएल वाले विकल्प

एचटीएमएल के अलावा, बीच में मौजूद फ़ाइलों के लिए कुछ अन्य विकल्प भी होते हैं:

  • आम तौर पर, उन ऐसेट की पहचान करें जो दूसरों पर असर नहीं डालती हैं

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

    • आपके उपयोगकर्ता शायद कई बार आपके किसी लेख पर जाकर न जाएं, इसलिए फ़ोटो या हीरो इमेज को हमेशा के लिए कैश मेमोरी में न रखें और स्टोरेज खाली न करें
  • ऐसी एसेट जो किसी ऐसी चीज़ को दिखाती है जिसका जीवन भर में मौजूद होता है

    • मौसम के बारे में JSON डेटा सिर्फ़ हर घंटे पब्लिश किया जाता है. इसलिए, पिछले नतीजे को एक घंटे तक कैश मेमोरी में सेव किया जा सकता है. इसका आपकी विंडो में कोई बदलाव नहीं होगा
    • ओपन-सोर्स प्रोजेक्ट के बिल्ड की दर सीमित हो सकती है. इसलिए, बिल्ड स्टेटस इमेज को तब तक कैश मेमोरी में सेव करें, जब तक कि स्टेटस बदल न जाए

खास जानकारी

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

कैश मेमोरी में सेव करना वेब पर नया कॉन्सेप्ट नहीं है, लेकिन शायद इसे ज़रूरत के हिसाब से डिफ़ॉल्ट माना जाए. इनमें से किसी एक का इस्तेमाल करें और ज़रूरत पड़ने पर बेहतर कैशिंग रणनीतियों के लिए ऑप्ट-इन करें. पढ़ने के लिए धन्यवाद!

इन्हें भी देखें

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