रनटाइम के दौरान संसाधनों को कैश मेमोरी में सेव करना

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

Workbox में, रूट को मैच करने के लिए workbox-routing मॉड्यूल का इस्तेमाल करके, ऐसेट के लिए रनटाइम को कैश मेमोरी में सेव किया जा सकता है. साथ ही, workbox-strategies मॉड्यूल की मदद से उनके लिए कैश मेमोरी की रणनीतियों को मैनेज किया जा सकता है.

कैश मेमोरी में सेव करने की रणनीतियां

एसेट के लिए ज़्यादातर रूट मैनेज किए जा सकते हैं. ऐसा, कैश मेमोरी में पहले से मौजूद किसी रणनीति से किया जा सकता है. इस बारे में ज़्यादा जानकारी इस दस्तावेज़ में पहले दी गई है, लेकिन यहां कुछ बातें दोबारा बताई गई हैं:

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

अनुरोधों को चुनने के लिए, इन रणनीतियों को लागू किया जा सकता है. इसके लिए, workbox-routing में दिए गए तरीकों का इस्तेमाल करें.

रूट मैचिंग के साथ कैश मेमोरी की रणनीतियां लागू करना

workbox-routing, रूट को मैच करने और उन्हें कैश मेमोरी की मदद से मैनेज करने के लिए, registerRoute तरीका दिखाता है. registerRoute एक Route ऑब्जेक्ट स्वीकार करता है, जो दो तर्क स्वीकार करता है:

  1. रूट मैचिंग की शर्तें बताने के लिए कोई स्ट्रिंग, रेगुलर एक्सप्रेशन या मैच कॉलबैक.
  2. रूट के लिए एक हैंडलर—आम तौर पर एक रणनीति जो workbox-strategies की ओर से दी जाती है.

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

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

// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';

// A new route that matches same-origin image requests and handles
// them with the cache-first, falling back to network strategy:
const imageRoute = new Route(({ request, sameOrigin }) => {
  return sameOrigin && request.destination === 'image'
}, new CacheFirst());

// Register the new route
registerRoute(imageRoute);

एक से ज़्यादा कैश मेमोरी का इस्तेमाल करना

वर्कबॉक्स की मदद से, कैश मेमोरी में सेव किए गए जवाबों को अलग-अलग Cache इंस्टेंस में बांटा जा सकता है. इसके लिए, बंडल की गई रणनीतियों में मौजूद cacheName विकल्प का इस्तेमाल किया जा सकता है.

यहां दिए गए उदाहरण में, इमेज में दोबारा पुष्टि करने के दौरान पुरानी रणनीति का इस्तेमाल किया गया है. वहीं, सीएसएस और JavaScript एसेट, पहले कैश मेमोरी में सेव डेटा पर वापस जाने वाली नेटवर्क रणनीति का इस्तेमाल करती हैं. हर एसेट के लिए रूट, cacheName प्रॉपर्टी को जोड़कर रिस्पॉन्स को अलग-अलग कैश मेमोरी में रखता है.

// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst, StaleWhileRevalidate } from 'workbox-strategies';

// Handle images:
const imageRoute = new Route(({ request }) => {
  return request.destination === 'image'
}, new StaleWhileRevalidate({
  cacheName: 'images'
}));

// Handle scripts:
const scriptsRoute = new Route(({ request }) => {
  return request.destination === 'script';
}, new CacheFirst({
  cacheName: 'scripts'
}));

// Handle styles:
const stylesRoute = new Route(({ request }) => {
  return request.destination === 'style';
}, new CacheFirst({
  cacheName: 'styles'
}));

// Register routes
registerRoute(imageRoute);
registerRoute(scriptsRoute);
registerRoute(stylesRoute);
Chrome के DevTools के ऐप्लिकेशन टैब में मौजूद, कैश मेमोरी के इंस्टेंस की सूची का स्क्रीनशॉट. यहां तीन अलग-अलग कैश मेमोरी दिखाई गई हैं: एक का नाम 'scripts', दूसरे का 'स्टाइल', और आखिरी का नाम 'इमेज' है.
Chrome DevTools के ऐप्लिकेशन पैनल में, कैश मेमोरी का व्यूअर. अलग-अलग तरह की एसेट से जुड़े जवाबों को अलग-अलग कैश मेमोरी में सेव किया जाता है.

कैश एंट्री के लिए, समयसीमा खत्म होने की तारीख सेट करना

सर्विस वर्कर कैश मेमोरी को मैनेज करते समय, स्टोरेज कोटा का ध्यान रखें. ExpirationPlugin, कैश मेमोरी के रखरखाव को आसान बनाता है और workbox-expiration इसे दिखाता है. इसका इस्तेमाल करने के लिए, इसे कैश मेमोरी की रणनीति के कॉन्फ़िगरेशन में तय करें:

// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
import { ExpirationPlugin } from 'workbox-expiration';

// Evict image cache entries older thirty days:
const imageRoute = new Route(({ request }) => {
  return request.destination === 'image';
}, new CacheFirst({
  cacheName: 'images',
  plugins: [
    new ExpirationPlugin({
      maxAgeSeconds: 60 * 60 * 24 * 30,
    })
  ]
}));

// Evict the least-used script cache entries when
// the cache has more than 50 entries:
const scriptsRoute = new Route(({ request }) => {
  return request.destination === 'script';
}, new CacheFirst({
  cacheName: 'scripts',
  plugins: [
    new ExpirationPlugin({
      maxEntries: 50,
    })
  ]
}));

// Register routes
registerRoute(imageRoute);
registerRoute(scriptsRoute);

स्टोरेज कोटा की शर्तों का पालन करना मुश्किल हो सकता है. ऐसे उपयोगकर्ताओं के बारे में जानना सही रहेगा जो ज़्यादा स्टोरेज का इस्तेमाल कर रहे हैं या जिन्हें स्टोरेज का बेहतर तरीके से इस्तेमाल करना है. वर्कबॉक्स के ExpirationPlugin पेयर उस लक्ष्य को पाने में मदद कर सकते हैं.

क्रॉस-ऑरिजिन पर ध्यान देना

आपके सर्विस वर्कर और क्रॉस-ऑरिजिन ऐसेट के बीच का इंटरैक्शन, एक ही ऑरिजिन वाली ऐसेट के बीच होने वाले इंटरैक्शन से काफ़ी अलग होता है. क्रॉस-ऑरिजिन रिसॉर्स शेयरिंग (सीओआरएस) को समझना मुश्किल है. यह जटिलता, सर्विस वर्कर में क्रॉस-ऑरिजिन रिसॉर्स को मैनेज करने के तरीके पर निर्भर करती है.

ओपेक रिस्पॉन्स

no-cors मोड में क्रॉस-ऑरिजिन अनुरोध करते समय, रिस्पॉन्स को सर्विस वर्कर की कैश मेमोरी में सेव किया जा सकता है और सीधे ब्राउज़र भी इसका इस्तेमाल कर सकता है. हालांकि, रिस्पॉन्स के मुख्य हिस्से को JavaScript से नहीं पढ़ा जा सकता. इसे ओपेक रिस्पॉन्स कहा जाता है.

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

सीओआरएस मोड को ऑप्ट इन करना न भूलें

भले ही, ऐसी क्रॉस-ऑरिजिन एसेट लोड की गई हों जो अनुमति वाले सीओआरएस हेडर सेट करते हैं, ताकि आप जवाबों को पढ़ सकें. हालांकि, क्रॉस-ऑरिजिन रिस्पॉन्स का मुख्य हिस्सा अब भी ओपेक हो सकता है. उदाहरण के लिए, यहां दिया गया एचटीएमएल, no-cors अनुरोधों को ट्रिगर करेगा. इससे, इस बात पर ध्यान दिए बिना कि सीओआरएस हेडर क्या सेट किए गए हैं, ओपेक रिस्पॉन्स मिलेंगे:

<link rel="stylesheet" href="https://example.com/path/to/style.css">
<img src="https://example.com/path/to/image.png">

साफ़ तौर पर cors अनुरोध को ट्रिगर करने के लिए, जो नॉन-ओपेक रिस्पॉन्स देगा, आपको अपने एचटीएमएल में crossorigin एट्रिब्यूट जोड़कर, साफ़ तौर पर सीओआरएस मोड में ऑप्ट-इन करना होगा:

<link crossorigin="anonymous" rel="stylesheet" href="https://example.com/path/to/style.css">
<img crossorigin="anonymous" src="https://example.com/path/to/image.png">

यह याद रखना ज़रूरी है कि आपके सर्विस वर्कर के रूट में रनटाइम के दौरान, सबरिसॉर्स कब लोड होते हैं.

हो सकता है कि वर्कबॉक्स ओपेक रिस्पॉन्स को कैश मेमोरी में सेव न करे

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

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

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

ओपेक रिस्पॉन्स को कैश मेमोरी में सेव करने की सुविधा चालू करें

अगर आपको पूरा यकीन है कि आपको कैश-फ़र्स्ट या सिर्फ़ कैश मेमोरी इस्तेमाल करके, ओपेक रिस्पॉन्स को कैश मेमोरी में सेव करना है, तो workbox-cacheable-response मॉड्यूल का इस्तेमाल करके Workbox को ऐसा करने के लिए मजबूर किया जा सकता है:

import {Route, registerRoute} from 'workbox-routing';
import {NetworkFirst, StaleWhileRevalidate} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';

const cdnRoute = new Route(({url}) => {
  return url === 'https://cdn.google.com/example-script.min.js';
}, new CacheFirst({
  plugins: [
    new CacheableResponsePlugin({
      statuses: [0, 200]
    })
  ]
}))

registerRoute(cdnRoute);

ओपेक रिस्पॉन्स और navigator.storage एपीआई

क्रॉस-डोमेन जानकारी को लीक होने से बचाने के लिए, स्टोरेज कोटा की सीमाओं का हिसाब लगाने के लिए इस्तेमाल किए जाने वाले ओपेक रिस्पॉन्स के साइज़ में ज़रूरी पैडिंग (जगह) जोड़ी गई है. इससे navigator.storage API, स्टोरेज कोटा को रिपोर्ट करने के तरीके पर असर डालता है.

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