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

सर्विस वर्कर के साथ प्रीफ़ेच करने की परंपरागत तकनीक को ज़्यादा बेहतर बनाया जा रहा है.

डेमियन रेंज़ुली
डेमियन रेंज़ुली
गिल्बर्टो कोची
गिल्बर्टो कोची
जेफ़ पॉसनिक
जेफ़ पॉस्निक

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

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

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

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

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

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

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

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

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

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

Virgilio Sport का लोगो.

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

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

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

नीचे दिए गए सेक्शन में, हम 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 मिनट है.

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

पिछले उदाहरण में, Workbox रनटाइम को कैश मेमोरी में सेव करने की रणनीति की मदद से, प्रॉडक्ट पेज को प्रीफ़ेच करने के लिए इस्तेमाल किए गए <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
  }
});