झटपट नेविगेशन का अनुभव

सर्विस वर्कर के साथ, प्रीफ़ेच करने की पारंपरिक तकनीकों को बेहतर बनाना.

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

तकनीकी शब्दों में, अलग-अलग पेजों पर जाने का मतलब नेविगेशन अनुरोध करना होता है. सामान्य नियम के तौर पर, नेविगेशन के अनुरोध के एचटीएमएल रिस्पॉन्स को कैश मेमोरी में सेव करने के लिए, आपको लंबे समय से इस्तेमाल होने वाले Cache-Control हेडर का इस्तेमाल नहीं करना है. आम तौर पर, उन्हें नेटवर्क के ज़रिए, Cache-Control: no-cache के ज़रिए संतुष्ट होना चाहिए. इससे यह पक्का किया जा सकेगा कि एचटीएमएल और बाद वाले नेटवर्क अनुरोधों की चेन, (तय) नया है. दुर्भाग्य से, उपयोगकर्ता के किसी नए पेज पर हर बार नेविगेट करने पर नेटवर्क पर जाने की समस्या का मतलब यह है कि हर नेविगेशन धीमा हो सकता है—कम से कम इसका मतलब है कि वह भरोसेमंद नहीं होगा.

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

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

प्रोडक्शन केस

MercadoLibre, लैटिन अमेरिका की सबसे बड़ी ई-कॉमर्स साइट है. नेविगेशन की रफ़्तार को बढ़ाने के लिए, ये डाइनैमिक तरीके से फ़्लो के कुछ हिस्सों में <link rel="prefetch"> टैग इंजेक्ट करते हैं. उदाहरण के लिए, लिस्टिंग वाले पेजों में, उपयोगकर्ता के स्टोर पेज पर नीचे की ओर स्क्रोल करते ही वे नतीजों वाले अगले पेज को फ़ेच कर लेते हैं:

MercadoLibre के लिस्टिंग पेज एक और दो और लिंक प्रीफ़ेच टैग दोनों को कनेक्ट करने का स्क्रीनशॉट.

प्रीफ़ेच की गई फ़ाइलों का अनुरोध "सबसे कम" प्राथमिकता पर किया जाता है. साथ ही, उन्हें एचटीटीपी कैश या मेमोरी कैश (इस आधार पर कि संसाधन कैश किया जा सकता है या नहीं) में सेव किया जाता है. यह अलग-अलग ब्राउज़र के हिसाब से अलग-अलग समय पर होता है. उदाहरण के लिए, Chrome 85 के हिसाब से, यह वैल्यू 5 मिनट है. संसाधनों को करीब पांच मिनट तक रखा जाता है. इसके बाद, संसाधन के लिए Cache-Control के सामान्य नियम लागू होते हैं.

सर्विस वर्कर कैश मेमोरी का इस्तेमाल करने से, प्रीफ़ेच किए गए संसाधनों की समयसीमा को पांच मिनट से ज़्यादा बढ़ाने में मदद मिल सकती है.

उदाहरण के लिए, इटैलियन स्पोर्ट्स पोर्टल Virgilio Sports चैनल के लोग, अपने होम पेज पर सबसे लोकप्रिय पोस्ट को प्रीफ़ेच करने के लिए, सर्विस वर्कर का इस्तेमाल करते हैं. वे Network Information API का इस्तेमाल भी करते हैं, ताकि 2G कनेक्शन का इस्तेमाल करने वाले उपयोगकर्ताओं को प्रीफ़ेच न किया जाए.

Virgilio Sports का लोगो.

इस वजह से, Virgilio दिन के तीन हफ़्तों के दौरान लेखों पर नेविगेट करने का लोड होने में 78% सुधार हुआ और लेख के इंप्रेशन की संख्या में 45% की बढ़ोतरी हुई.

Virgilio Sports के होम पेज और लेख के पेजों का स्क्रीनशॉट. इसमें प्रीफ़ेच करने के बाद, असर दिखाने वाली मेट्रिक दिख रही हैं.

Workbox की मदद से, प्रीकैशिंग को लागू करना

नीचे दिए गए सेक्शन में, हम वर्कबॉक्स का इस्तेमाल करके यह दिखाएंगे कि सर्विस वर्कर में अलग-अलग कैश मेमोरी बनाने की तकनीकों को कैसे लागू किया जाए. सर्विस वर्कर को यह टास्क पूरी तरह से सौंपकर, <link rel="prefetch"> के पूरक के तौर पर या यहां तक कि इसकी जगह भी इसका इस्तेमाल किया जा सकता है.

1. स्टैटिक पेजों और पेज सबरिसॉर्स को पहले ही कैश मेमोरी में सेव करें

प्रीकैशिंग, सर्विस वर्कर की वह क्षमता है जो इंस्टॉल होने के दौरान कैश मेमोरी में फ़ाइलें सेव कर सकता है.

नीचे दिए गए मामलों में, प्रीकैशिंग का इस्तेमाल प्रीफ़ेच करने से मिलते-जुलते लक्ष्य को पाने के लिए किया जाता है: नेविगेशन को तेज़ बनाना.

स्टैटिक पेजों को पहले से कैश मेमोरी में सेव करना

बिल्ड के समय (जैसे about.html, contact.html) या पूरी तरह से स्टैटिक साइटों में जनरेट किए गए पेजों के लिए, साइट के दस्तावेज़ों को प्रीकैश सूची में जोड़ा जा सकता है. इससे, उपयोगकर्ता जब भी उन्हें ऐक्सेस करता है, तो वे पहले से ही कैश मेमोरी में उपलब्ध रहते हैं:

workbox.precaching.precacheAndRoute([
  {url: '/about.html', revision: 'abcd1234'},
  // ... other entries ...
]);

पेज के उप-संसाधनों को पहले से कैश मेमोरी में सेव करना

साइट के अलग-अलग सेक्शन (उदाहरण के लिए, JavaScript, सीएसएस वगैरह) का इस्तेमाल करने वाले स्टैटिक एसेट को पहले से कैश मेमोरी में सेव करना, सबसे सही तरीका है. इससे प्रीफ़ेच करने की प्रोसेस को बेहतर बनाया जा सकता है.

किसी ई-कॉमर्स साइट में नेविगेशन की स्पीड बढ़ाने के लिए, लिस्टिंग पेजों में <link rel="prefetch"> टैग का इस्तेमाल किया जा सकता है. इससे किसी लिस्टिंग पेज के शुरुआती कुछ प्रॉडक्ट के लिए, प्रॉडक्ट की जानकारी वाले पेजों को प्रीफ़ेच किया जा सकता है. अगर आपने प्रॉडक्ट पेज के सबरिसॉर्स को पहले ही प्रीकैश कर लिया है, तो इससे नेविगेशन और भी तेज़ हो सकता है.

इसे लागू करने के लिए:

  • पेज में <link rel="prefetch"> टैग जोड़ें:
 <link rel="prefetch" href="/phones/smartphone-5x.html" as="document">
  • सर्विस वर्कर में, पेज के सबरिसॉर्स को प्रीकैश सूची में जोड़ें:
workbox.precaching.precacheAndRoute([
  '/styles/product-page.ac29.css',
  // ... other entries ...
]);

2. प्रीफ़ेच संसाधनों के इस्तेमाल की अवधि बढ़ाएं

जैसा कि पहले बताया गया है, <link rel="prefetch">, संसाधनों को फ़ेच करता है और सीमित समय के लिए उन्हें एचटीटीपी कैश में रखता है. इसके बाद, किसी संसाधन के लिए Cache-Control के नियम लागू होते हैं. Chrome 85 के हिसाब से, यह वैल्यू 5 मिनट है.

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

पिछले उदाहरण में, वर्कबॉक्स रनटाइम कैश मेमोरी की रणनीति के साथ प्रॉडक्ट पेज को प्रीफ़ेच करने के लिए इस्तेमाल किए गए <link rel="prefetch"> को बेहतर बनाया जा सकता है.

इसे लागू करने के लिए:

  • पेज में <link rel="prefetch"> टैग जोड़ें:
 <link rel="prefetch" href="/phones/smartphone-5x.html" as="document">
  • इस तरह के अनुरोधों के लिए, सर्विस वर्कर में रनटाइम कैश मेमोरी की रणनीति लागू करें:
new workbox.strategies.StaleWhileRevalidate({
  cacheName: 'document-cache',
  plugins: [
    new workbox.expiration.Plugin({
      maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
    }),
  ],
});

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

3. सर्विस वर्कर को प्रीफ़ेच करने का ऐक्सेस देना

ज़्यादातर मामलों में, <link rel="prefetch"> का इस्तेमाल करना सबसे सही तरीका होता है. यह टैग एक संसाधन संकेत है, जिसे प्रीफ़ेच करने की सुविधा को ज़्यादा से ज़्यादा कारगर बनाने के लिए डिज़ाइन किया गया है.

हालांकि, कुछ मामलों में बेहतर यही होगा कि यह काम पूरी तरह सर्विस वर्कर को दिया जाए. उदाहरण के लिए: क्लाइंट-साइड से रेंडर की गई प्रॉडक्ट लिस्टिंग वाले पेज पर पहले कुछ प्रॉडक्ट को प्रीफ़ेच करने के लिए, एपीआई से मिले रिस्पॉन्स के आधार पर, पेज में डाइनैमिक तौर पर कई <link rel="prefetch"> टैग इंजेक्ट करने पड़ सकते हैं. इससे, कुछ समय के लिए पेज के मुख्य थ्रेड पर ज़्यादा समय लग सकता है. साथ ही, यह लागू करने का तरीका और मुश्किल हो सकता है.

इस तरह के मामलों में, प्रीफ़ेच करने का काम पूरी तरह से सर्विस वर्कर को सौंपने के लिए "सर्विस वर्कर कम्यूनिकेशन स्ट्रेटजी के लिए पेज" का इस्तेमाल करें. इस तरह का संचार worker.postMessage() का इस्तेमाल करके किया जा सकता है:

पेज का आइकॉन, जो सर्विस वर्कर के साथ दो-तरफ़ा बातचीत करता है.

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

Workbox विंडो के साथ प्रीफ़ेच को नीचे दिए गए तरीके से लागू किया जा सकता है:

  • पेज में: सर्विस वर्कर को कॉल करें और यह बताएं कि वह मैसेज किस तरह का है. साथ ही, प्रीफ़ेच किए जाने वाले यूआरएल की सूची होनी चाहिए:
const wb = new Workbox('/sw.js');
wb.register();

const prefetchResponse = await wb.messageSW({type: 'PREFETCH_URLS', urls: […]});
  • सर्विस वर्कर में: प्रीफ़ेच के लिए हर यूआरएल के लिए fetch() अनुरोध जारी करने के लिए, मैसेज हैंडलर लागू करें:
addEventListener('message', (event) => {
  if (event.data.type === 'PREFETCH_URLS') {
    // Fetch URLs and store them in the cache
  }
});