পরিষেবা কর্মী ক্যাশিং জন্য কৌশল

এখন পর্যন্ত, Cache ইন্টারফেসের শুধুমাত্র উল্লেখ এবং ছোট কোড স্নিপেট আছে। পরিষেবা কর্মীদের কার্যকরভাবে ব্যবহার করার জন্য, এক বা একাধিক ক্যাশিং কৌশল গ্রহণ করা প্রয়োজন, যার জন্য Cache ইন্টারফেসের সাথে কিছুটা পরিচিতি প্রয়োজন।

একটি ক্যাশিং কৌশল হল একটি পরিষেবা কর্মীর fetch ইভেন্ট এবং Cache ইন্টারফেসের মধ্যে একটি মিথস্ক্রিয়া। একটি ক্যাশিং কৌশল কীভাবে লেখা হয় তা নির্ভর করে; উদাহরণস্বরূপ, স্ট্যাটিক সম্পদের অনুরোধগুলি নথির চেয়ে ভিন্নভাবে পরিচালনা করা বাঞ্ছনীয় হতে পারে এবং এটি ক্যাশিং কৌশল কীভাবে তৈরি করা হয় তা প্রভাবিত করে।

আমরা নিজেরাই কৌশলগুলিতে প্রবেশ করার আগে, Cache ইন্টারফেসটি কী নয়, এটি কী এবং পরিষেবা কর্মী ক্যাশে পরিচালনা করার জন্য এটি যে পদ্ধতিগুলি অফার করে তার একটি দ্রুত সংক্ষিপ্ত বিবরণ সম্পর্কে কথা বলতে এক সেকেন্ড সময় নেওয়া যাক।

Cache ইন্টারফেস বনাম HTTP ক্যাশে

আপনি যদি আগে Cache ইন্টারফেসের সাথে কাজ না করে থাকেন, তাহলে এটিকে HTTP ক্যাশের মতোই বা অন্ততপক্ষে সম্পর্কিত হিসাবে ভাবতে প্রলুব্ধ হতে পারে। এই ব্যাপারটা নয়।

  • Cache ইন্টারফেস হল একটি ক্যাশিং মেকানিজম যা HTTP ক্যাশে থেকে সম্পূর্ণ আলাদা।
  • এইচটিটিপি ক্যাশে প্রভাবিত করার জন্য আপনি যে Cache-Control কনফিগারেশন ব্যবহার করুন না কেন Cache ইন্টারফেসে কোন সম্পদ সংরক্ষণ করা হয় তার উপর কোন প্রভাব নেই।

এটি ব্রাউজার ক্যাশেগুলিকে স্তরযুক্ত হিসাবে ভাবতে সহায়তা করে। HTTP ক্যাশে হল একটি নিম্ন-স্তরের ক্যাশে যা HTTP শিরোনামে প্রকাশ করা নির্দেশাবলী সহ কী-মান জোড়া দ্বারা চালিত হয়।

বিপরীতে, Cache ইন্টারফেস হল একটি উচ্চ-স্তরের ক্যাশে যা একটি JavaScript API দ্বারা চালিত হয়। তুলনামূলকভাবে সরল HTTP কী-মান জোড়া ব্যবহার করার তুলনায় এটি আরও নমনীয়তা প্রদান করে এবং ক্যাশিং কৌশলগুলিকে সম্ভব করে তোলে তার অর্ধেক। পরিষেবা কর্মী ক্যাশেগুলির চারপাশে কিছু গুরুত্বপূর্ণ API পদ্ধতিগুলি হল:

  • একটি নতুন Cache উদাহরণ তৈরি করতে CacheStorage.open
  • একটি পরিষেবা কর্মী ক্যাশে নেটওয়ার্ক প্রতিক্রিয়া সংরক্ষণ করতে Cache.add এবং Cache.put .
  • Cache.match একটি Cache উদাহরণে একটি ক্যাশে করা প্রতিক্রিয়া সনাক্ত করতে।
  • একটি Cache ইনস্ট্যান্স থেকে একটি ক্যাশে করা প্রতিক্রিয়া সরাতে Cache.delete .

এই মাত্র কয়েক. অন্যান্য দরকারী পদ্ধতি রয়েছে, তবে এইগুলি হল প্রাথমিক পদ্ধতিগুলি যা আপনি এই নির্দেশিকায় পরে ব্যবহার করতে দেখতে পাবেন।

বিনীত fetch ঘটনা

একটি ক্যাশিং কৌশলের বাকি অর্ধেক হল পরিষেবা কর্মীর fetch ইভেন্ট । এখন পর্যন্ত এই ডকুমেন্টেশনে, আপনি "নেটওয়ার্কের অনুরোধে বাধা দেওয়ার" সম্পর্কে কিছুটা শুনেছেন এবং একজন পরিষেবা কর্মীর ভিতরে fetch ইভেন্টটি যেখানে এটি ঘটে:

// Establish a cache name
const cacheName = 'MyFancyCacheName_v1';

self.addEventListener('install', (event) => {
  event.waitUntil(caches.open(cacheName));
});

self.addEventListener('fetch', async (event) => {
  // Is this a request for an image?
  if (event.request.destination === 'image') {
    // Open the cache
    event.respondWith(caches.open(cacheName).then((cache) => {
      // Respond with the image from the cache or from the network
      return cache.match(event.request).then((cachedResponse) => {
        return cachedResponse || fetch(event.request.url).then((fetchedResponse) => {
          // Add the network response to the cache for future visits.
          // Note: we need to make a copy of the response to save it in
          // the cache and use the original as the request response.
          cache.put(event.request, fetchedResponse.clone());

          // Return the network response
          return fetchedResponse;
        });
      });
    }));
  } else {
    return;
  }
});

এটি একটি খেলনা উদাহরণ—এবং আপনি নিজের জন্য কাজ করতে দেখতে পারেন —কিন্তু এটি এমন একটি যা পরিষেবা কর্মীরা কী করতে পারে তার একটি আভাস দেয়৷ উপরের কোড নিম্নলিখিত কাজ করে:

  1. এটি একটি চিত্র অনুরোধ কিনা তা দেখতে অনুরোধের destination সম্পত্তি পরিদর্শন করুন।
  2. যদি ছবিটি পরিষেবা কর্মী ক্যাশে থাকে তবে সেখান থেকে পরিবেশন করুন। যদি না হয়, নেটওয়ার্ক থেকে ছবিটি আনুন, প্রতিক্রিয়াটি ক্যাশে সংরক্ষণ করুন এবং নেটওয়ার্ক প্রতিক্রিয়া ফেরত দিন।
  3. অন্যান্য সমস্ত অনুরোধ ক্যাশের সাথে কোনও মিথস্ক্রিয়া ছাড়াই পরিষেবা কর্মীর মাধ্যমে পাস করা হয়।

একটি আনয়নের event অবজেক্টে একটি request সম্পত্তি রয়েছে যা আপনাকে প্রতিটি অনুরোধের ধরন সনাক্ত করতে সহায়তা করার জন্য কিছু দরকারী তথ্য বিট রয়েছে:

  • url , যা বর্তমানে fetch ইভেন্ট দ্বারা পরিচালিত নেটওয়ার্ক অনুরোধের URL।
  • method , যা অনুরোধের পদ্ধতি (যেমন, GET বা POST )।
  • mode , যা অনুরোধের মোড বর্ণনা করে। 'navigate' এর একটি মান প্রায়শই অন্যান্য অনুরোধ থেকে HTML নথির অনুরোধগুলিকে আলাদা করতে ব্যবহৃত হয়।
  • destination , যা অনুরোধকৃত সম্পদের ফাইল এক্সটেনশন ব্যবহার এড়াতে অনুরোধ করা বিষয়বস্তুর ধরন বর্ণনা করে।

আবারও, অ্যাসিঙ্ক্রোনি গেমটির নাম। আপনি মনে রাখবেন যে install ইভেন্টটি একটি event.waitUntil পদ্ধতি অফার করে যা একটি প্রতিশ্রুতি নেয় এবং সক্রিয়করণ চালিয়ে যাওয়ার আগে এটি সমাধানের জন্য অপেক্ষা করে। fetch ইভেন্টটি একটি অনুরূপ event.respondWith পদ্ধতি অফার করে যা আপনি একটি অ্যাসিঙ্ক্রোনাস fetch অনুরোধের ফলাফল বা Cache ইন্টারফেসের match পদ্ধতি দ্বারা প্রত্যাবর্তিত প্রতিক্রিয়া ফেরাতে ব্যবহার করতে পারেন৷

ক্যাশিং কৌশল

এখন যেহেতু আপনি Cache উদাহরণ এবং fetch ইভেন্ট হ্যান্ডলারের সাথে কিছুটা পরিচিতি পেয়েছেন, আপনি কিছু পরিষেবা কর্মী ক্যাশিং কৌশলগুলিতে ডুব দিতে প্রস্তুত৷ যদিও সম্ভাবনাগুলি কার্যত অন্তহীন, এই নির্দেশিকাটি ওয়ার্কবক্সের সাথে পাঠানো কৌশলগুলির সাথে লেগে থাকবে, যাতে আপনি ওয়ার্কবক্সের অভ্যন্তরীণ অংশে কী ঘটছে তা বুঝতে পারেন।

শুধুমাত্র ক্যাশে

পৃষ্ঠা থেকে, পরিষেবা কর্মী, ক্যাশে প্রবাহ দেখায়।

আসুন একটি সাধারণ ক্যাশিং কৌশল দিয়ে শুরু করি যা আমরা বলব "কেবলমাত্র ক্যাশে"। এটা ঠিক যে: যখন পরিষেবা কর্মী পৃষ্ঠার নিয়ন্ত্রণে থাকে, তখন মিলিত অনুরোধগুলি শুধুমাত্র ক্যাশে যাবে। এর মানে হল যে প্যাটার্ন কাজ করার জন্য উপলব্ধ হওয়ার জন্য যেকোনও ক্যাশে করা সম্পদগুলিকে প্রাক-ক্যাচ করতে হবে এবং পরিষেবা কর্মী আপডেট না হওয়া পর্যন্ত সেই সম্পদগুলি কখনই ক্যাশে আপডেট করা হবে না৷

// Establish a cache name
const cacheName = 'MyFancyCacheName_v1';

// Assets to precache
const precachedAssets = [
  '/possum1.jpg',
  '/possum2.jpg',
  '/possum3.jpg',
  '/possum4.jpg'
];

self.addEventListener('install', (event) => {
  // Precache assets on install
  event.waitUntil(caches.open(cacheName).then((cache) => {
    return cache.addAll(precachedAssets);
  }));
});

self.addEventListener('fetch', (event) => {
  // Is this one of our precached assets?
  const url = new URL(event.request.url);
  const isPrecachedRequest = precachedAssets.includes(url.pathname);

  if (isPrecachedRequest) {
    // Grab the precached asset from the cache
    event.respondWith(caches.open(cacheName).then((cache) => {
      return cache.match(event.request.url);
    }));
  } else {
    // Go to the network
    return;
  }
});

উপরে, সম্পদের একটি অ্যারে ইনস্টল করার সময় প্রিক্যাচ করা হয়। যখন পরিষেবা কর্মী ফেচগুলি পরিচালনা করেন, তখন আমরা পরীক্ষা করে দেখি যে fetch ইভেন্ট দ্বারা পরিচালিত অনুরোধ URLটি প্রিক্যাচ করা সম্পদের অ্যারেতে আছে কিনা৷ যদি তাই হয়, আমরা ক্যাশে থেকে সংস্থানটি দখল করি এবং নেটওয়ার্কটি এড়িয়ে যাই। অন্যান্য অনুরোধ নেটওয়ার্কের মাধ্যমে পাস, এবং শুধুমাত্র নেটওয়ার্ক. এই কৌশলটি কার্যকর দেখতে, আপনার কনসোল খোলার সাথে এই ডেমোটি দেখুন

শুধুমাত্র নেটওয়ার্ক

পৃষ্ঠা থেকে, পরিষেবা কর্মী, নেটওয়ার্কে প্রবাহ দেখায়।

"শুধুমাত্র ক্যাশে" এর বিপরীতটি হল "নেটওয়ার্ক শুধুমাত্র", যেখানে পরিষেবা কর্মী ক্যাশের সাথে কোনও ইন্টারঅ্যাকশন ছাড়াই কোনও পরিষেবাকর্মীর মাধ্যমে নেটওয়ার্কে একটি অনুরোধ পাঠানো হয়। বিষয়বস্তুর সতেজতা নিশ্চিত করার জন্য এটি একটি ভাল কৌশল (চিন্তা মার্কআপ), কিন্তু ট্রেডঅফ হল যে ব্যবহারকারী অফলাইনে থাকলে এটি কখনই কাজ করবে না।

একটি অনুরোধ নেটওয়ার্কের মাধ্যমে পাস করা নিশ্চিত করার মানে হল আপনি একটি মিলিত অনুরোধের জন্য event.respondWith কল করবেন না৷ আপনি যদি স্পষ্ট হতে চান, আপনি একটি খালি return; আপনি নেটওয়ার্কের মাধ্যমে পাস করতে চান অনুরোধের জন্য আপনার fetch ইভেন্ট কলব্যাক. প্রিক্যাচ করা হয়নি এমন অনুরোধগুলির জন্য "শুধুমাত্র ক্যাশে" কৌশল ডেমোতে এটি ঘটে।

প্রথমে ক্যাশে, নেটওয়ার্কে ফিরে আসা

পৃষ্ঠা থেকে প্রবাহ দেখায়, পরিষেবা কর্মী, ক্যাশে, তারপর ক্যাশে না থাকলে নেটওয়ার্কে।

এই কৌশলটি হল যেখানে জিনিসগুলি একটু বেশি জড়িত। মিলিত অনুরোধের জন্য, প্রক্রিয়াটি এইরকম হয়:

  1. অনুরোধ ক্যাশে হিট. সম্পদ ক্যাশে থাকলে, সেখান থেকে পরিবেশন করুন।
  2. অনুরোধটি ক্যাশে না থাকলে, নেটওয়ার্কে যান।
  3. একবার নেটওয়ার্ক অনুরোধ শেষ হলে, এটি ক্যাশে যোগ করুন, তারপর নেটওয়ার্ক থেকে প্রতিক্রিয়া ফেরত দিন।

এখানে এই কৌশলটির একটি উদাহরণ, যা আপনি একটি লাইভ ডেমোতে পরীক্ষা করতে পারেন:

// Establish a cache name
const cacheName = 'MyFancyCacheName_v1';

self.addEventListener('fetch', (event) => {
  // Check if this is a request for an image
  if (event.request.destination === 'image') {
    event.respondWith(caches.open(cacheName).then((cache) => {
      // Go to the cache first
      return cache.match(event.request.url).then((cachedResponse) => {
        // Return a cached response if we have one
        if (cachedResponse) {
          return cachedResponse;
        }

        // Otherwise, hit the network
        return fetch(event.request).then((fetchedResponse) => {
          // Add the network response to the cache for later visits
          cache.put(event.request, fetchedResponse.clone());

          // Return the network response
          return fetchedResponse;
        });
      });
    }));
  } else {
    return;
  }
});

যদিও এই উদাহরণটি শুধু ছবিগুলিকে কভার করে, এটি সমস্ত স্ট্যাটিক সম্পদ (যেমন CSS, JavaScript, ছবি এবং ফন্ট) বিশেষ করে হ্যাশ-সংস্করণে প্রয়োগ করার জন্য একটি দুর্দান্ত কৌশল। HTTP ক্যাশে চালু হতে পারে এমন সার্ভারের সাথে যেকোনো বিষয়বস্তুর সতেজতা চেক করার মাধ্যমে এটি অপরিবর্তনীয় সম্পদের জন্য গতি বৃদ্ধির প্রস্তাব দেয়। আরও গুরুত্বপূর্ণ, যেকোন ক্যাশে করা সম্পদ অফলাইনে পাওয়া যাবে।

নেটওয়ার্ক প্রথম, ক্যাশে ফিরে পতনশীল

পৃষ্ঠা থেকে প্রবাহ দেখায়, পরিষেবা কর্মী, নেটওয়ার্ক, তারপর ক্যাশে যদি নেটওয়ার্ক উপলব্ধ না হয়।

আপনি যদি এর মাথায় "ক্যাশে ফার্স্ট, নেটওয়ার্ক সেকেন্ড" ফ্লিপ করেন, তাহলে আপনি "নেটওয়ার্ক ফার্স্ট, ক্যাশে সেকেন্ড" কৌশলটি শেষ করবেন, যা এটির মতো শোনাচ্ছে:

  1. আপনি একটি অনুরোধের জন্য প্রথমে নেটওয়ার্কে যান, এবং প্রতিক্রিয়াটি ক্যাশে রাখুন।
  2. আপনি যদি পরবর্তী সময়ে অফলাইনে থাকেন, আপনি ক্যাশে সেই প্রতিক্রিয়াটির সর্বশেষ সংস্করণে ফিরে যাবেন।

এই কৌশলটি এইচটিএমএল বা API অনুরোধের জন্য দুর্দান্ত যখন, অনলাইনে থাকাকালীন, আপনি কোনও সংস্থানের সাম্প্রতিকতম সংস্করণ চান, তবুও সাম্প্রতিক উপলব্ধ সংস্করণে অফলাইন অ্যাক্সেস দিতে চান। HTML এর জন্য অনুরোধে প্রয়োগ করার সময় এটি দেখতে কেমন হতে পারে তা এখানে রয়েছে:

// Establish a cache name
const cacheName = 'MyFancyCacheName_v1';

self.addEventListener('fetch', (event) => {
  // Check if this is a navigation request
  if (event.request.mode === 'navigate') {
    // Open the cache
    event.respondWith(caches.open(cacheName).then((cache) => {
      // Go to the network first
      return fetch(event.request.url).then((fetchedResponse) => {
        cache.put(event.request, fetchedResponse.clone());

        return fetchedResponse;
      }).catch(() => {
        // If the network is unavailable, get
        return cache.match(event.request.url);
      });
    }));
  } else {
    return;
  }
});

আপনি এটি একটি ডেমোতে চেষ্টা করে দেখতে পারেন। প্রথমে পেজে যান। HTML প্রতিক্রিয়া ক্যাশে স্থাপন করার আগে আপনাকে পুনরায় লোড করতে হতে পারে। তারপর আপনার বিকাশকারী সরঞ্জামগুলিতে, একটি অফলাইন সংযোগ অনুকরণ করুন এবং আবার পুনরায় লোড করুন৷ সর্বশেষ উপলব্ধ সংস্করণটি ক্যাশে থেকে অবিলম্বে পরিবেশন করা হবে।

এমন পরিস্থিতিতে যেখানে অফলাইন সক্ষমতা গুরুত্বপূর্ণ, কিন্তু আপনাকে সেই সামর্থ্যের সাথে সামঞ্জস্য বজায় রাখতে হবে এবং কিছু মার্কআপ বা API ডেটার সাম্প্রতিক সংস্করণে অ্যাক্সেস করতে হবে, "নেটওয়ার্ক ফার্স্ট, ক্যাশে সেকেন্ড" একটি কঠিন কৌশল যা সেই লক্ষ্য অর্জন করে।

বাসি-যখন-পুনর্বিচার করা

পৃষ্ঠা থেকে, পরিষেবা কর্মী, ক্যাশে, তারপর নেটওয়ার্ক থেকে ক্যাশে প্রবাহ দেখায়।

আমরা এখন পর্যন্ত যে কৌশলগুলি কভার করেছি, তার মধ্যে "স্টেল-হোয়াইল-রিভ্যালিডেট" হল সবচেয়ে জটিল৷ এটি কিছু উপায়ে শেষ দুটি কৌশলের মতো, তবে পদ্ধতিটি একটি সংস্থানের অ্যাক্সেসের গতিকে অগ্রাধিকার দেয়, পাশাপাশি এটিকে পটভূমিতে আপ টু ডেট রাখে। এই কৌশলটি এরকম কিছু যায়:

  1. একটি সম্পদের জন্য প্রথম অনুরোধে, এটি নেটওয়ার্ক থেকে আনুন, এটি ক্যাশে রাখুন এবং নেটওয়ার্ক প্রতিক্রিয়া ফেরত দিন৷
  2. পরবর্তী অনুরোধে, প্রথমে ক্যাশে থেকে সম্পদটি পরিবেশন করুন, তারপর "পটভূমিতে", নেটওয়ার্ক থেকে এটিকে পুনরায় অনুরোধ করুন এবং সম্পদের ক্যাশে এন্ট্রি আপডেট করুন।
  3. এর পরে অনুরোধের জন্য, আপনি নেটওয়ার্ক থেকে আনা শেষ সংস্করণটি পাবেন যা আগের ধাপে ক্যাশে রাখা হয়েছিল।

এটি এমন জিনিসগুলির জন্য একটি চমৎকার কৌশল যা আপ টু ডেট রাখা গুরুত্বপূর্ণ , কিন্তু গুরুত্বপূর্ণ নয়। সোশ্যাল মিডিয়া সাইটের জন্য অবতারের মতো জিনিসের কথা ভাবুন। ব্যবহারকারীরা যখন এটি করতে আসে তখন তারা আপডেট হয়, তবে প্রতিটি অনুরোধে সর্বশেষ সংস্করণটি কঠোরভাবে প্রয়োজনীয় নয়।

// Establish a cache name
const cacheName = 'MyFancyCacheName_v1';

self.addEventListener('fetch', (event) => {
  if (event.request.destination === 'image') {
    event.respondWith(caches.open(cacheName).then((cache) => {
      return cache.match(event.request).then((cachedResponse) => {
        const fetchedResponse = fetch(event.request).then((networkResponse) => {
          cache.put(event.request, networkResponse.clone());

          return networkResponse;
        });

        return cachedResponse || fetchedResponse;
      });
    }));
  } else {
    return;
  }
});

আপনি এটিকে আরও একটি লাইভ ডেমোতে দেখতে পারেন, বিশেষ করে যদি আপনি আপনার ব্রাউজারের বিকাশকারী সরঞ্জামগুলিতে নেটওয়ার্ক ট্যাবে এবং এর CacheStorage ভিউয়ারে মনোযোগ দেন (যদি আপনার ব্রাউজারের বিকাশকারী সরঞ্জামগুলিতে এমন একটি সরঞ্জাম থাকে)।

ওয়ার্কবক্সে এগিয়ে!

এই দস্তাবেজটি আমাদের পরিষেবা কর্মীর API, সেইসাথে সম্পর্কিত APIগুলির পর্যালোচনা গুটিয়ে রাখে, যার মানে আপনি ওয়ার্কবক্সের সাথে টিঙ্কারিং শুরু করতে পরিষেবা কর্মীদের সরাসরি কীভাবে ব্যবহার করবেন সে সম্পর্কে যথেষ্ট শিখেছেন!