স্ট্রিম সহ দ্রুত মাল্টিপেজ অ্যাপ্লিকেশন

আজকাল, ওয়েবসাইটগুলি—বা ওয়েব অ্যাপগুলি যদি আপনি পছন্দ করেন—দুটি নেভিগেশন স্কিমগুলির মধ্যে একটি ব্যবহার করার প্রবণতা রয়েছে:

  • নেভিগেশন স্কিম ব্রাউজারগুলি ডিফল্টরূপে প্রদান করে—অর্থাৎ, আপনি আপনার ব্রাউজারের ঠিকানা বারে একটি URL লিখুন এবং একটি নেভিগেশন অনুরোধ প্রতিক্রিয়া হিসাবে একটি নথি প্রদান করে৷ তারপরে আপনি একটি লিঙ্কে ক্লিক করুন, যা বর্তমান নথিটিকে অন্য একটির জন্য আনলোড করে, বিজ্ঞাপন অসীম
  • একক পৃষ্ঠার অ্যাপ্লিকেশন প্যাটার্ন, যাতে অ্যাপ্লিকেশন শেল লোড করার জন্য একটি প্রাথমিক নেভিগেশন অনুরোধ জড়িত থাকে এবং প্রতিটি "নেভিগেশন" এর জন্য একটি ব্যাক-এন্ড API থেকে সামগ্রী সহ ক্লায়েন্ট-রেন্ডার করা মার্কআপ সহ অ্যাপ্লিকেশন শেল তৈরি করতে জাভাস্ক্রিপ্টের উপর নির্ভর করে।

প্রতিটি পদ্ধতির সুবিধাগুলি তাদের সমর্থকদের দ্বারা চিহ্নিত করা হয়েছে:

  • ব্রাউজারগুলি ডিফল্টরূপে যে নেভিগেশন স্কিম সরবরাহ করে তা স্থিতিস্থাপক, কারণ রুটগুলিতে অ্যাক্সেসযোগ্য হওয়ার জন্য জাভাস্ক্রিপ্টের প্রয়োজন হয় না। জাভাস্ক্রিপ্টের মাধ্যমে মার্কআপের ক্লায়েন্ট-রেন্ডারিংও একটি সম্ভাব্য ব্যয়বহুল প্রক্রিয়া হতে পারে, যার অর্থ নিম্ন-প্রান্তের ডিভাইসগুলি এমন পরিস্থিতিতে শেষ হতে পারে যেখানে সামগ্রী বিলম্বিত হয় কারণ ডিভাইসটি সামগ্রী সরবরাহ করে এমন স্ক্রিপ্ট প্রক্রিয়াকরণ ব্লক করা হয়েছে৷
  • অন্যদিকে, একক পৃষ্ঠা অ্যাপ্লিকেশন (এসপিএ) প্রাথমিক লোডের পরে দ্রুত নেভিগেশন সরবরাহ করতে পারে। সম্পূর্ণ নতুন একটি নথি আনলোড করার জন্য ব্রাউজারে নির্ভর করার পরিবর্তে (এবং প্রতিটি নেভিগেশনের জন্য এটি পুনরাবৃত্তি করা) তারা একটি দ্রুততর, আরও "অ্যাপ-এর মতো" অভিজ্ঞতার মতো অনুভব করতে পারে—এমনকি যদি এটির জন্য JavaScript প্রয়োজন হয়।

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

কেন একটি পরিষেবা কর্মীর মধ্যে HTML প্রতিক্রিয়া স্ট্রিম?

স্ট্রিমিং এমন কিছু যা আপনার ওয়েব ব্রাউজার ইতিমধ্যেই করে যখন এটি অনুরোধ করে। ন্যাভিগেশন অনুরোধের পরিপ্রেক্ষিতে এটি অত্যন্ত গুরুত্বপূর্ণ, কারণ এটি নিশ্চিত করে যে ব্রাউজারটি ডকুমেন্ট মার্কআপ পার্স করা এবং একটি পৃষ্ঠা রেন্ডার করা শুরু করার আগে সম্পূর্ণ প্রতিক্রিয়ার জন্য অপেক্ষা করে অবরুদ্ধ নয়।

একটি চিত্র যা নন-স্ট্রিমিং HTML বনাম স্ট্রিমিং HTML চিত্রিত করে৷ পূর্বের ক্ষেত্রে, পুরো মার্কআপ পেলোডটি না আসা পর্যন্ত প্রক্রিয়া করা হয় না। পরবর্তীতে, মার্কআপ ক্রমবর্ধমানভাবে প্রক্রিয়া করা হয় কারণ এটি নেটওয়ার্ক থেকে খণ্ডে আসে।

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

এই অনুরোধগুলি বিভিন্ন উপায়ে ক্যাশের সাথে ইন্টারঅ্যাক্ট করতে পারে, তবে মার্কআপের জন্য একটি সাধারণ ক্যাশিং প্যাটার্ন হল প্রথমে নেটওয়ার্ক থেকে একটি প্রতিক্রিয়া ব্যবহার করার পক্ষে, কিন্তু যদি একটি পুরানো অনুলিপি পাওয়া যায় তবে ক্যাশে ফিরে আসা -এবং ঐচ্ছিকভাবে একটি জেনেরিক ফলব্যাক প্রদান করে একটি ব্যবহারযোগ্য প্রতিক্রিয়া ক্যাশে না থাকলে প্রতিক্রিয়া

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

একটি সাধারণ ওয়েব পৃষ্ঠা ভেঙে ফেলা

কাঠামোগতভাবে বলতে গেলে, ওয়েবসাইটের প্রতিটি পৃষ্ঠায় বিদ্যমান সাধারণ উপাদান থাকে । পৃষ্ঠা উপাদানগুলির একটি সাধারণ বিন্যাস প্রায়শই এরকম কিছু যায়:

  • হেডার।
  • বিষয়বস্তু।
  • ফুটার।

একটি উদাহরণ হিসাবে web.dev ব্যবহার করে, সাধারণ উপাদানগুলির ভাঙ্গন এইরকম দেখায়:

web.dev ওয়েবসাইটে সাধারণ উপাদানগুলির একটি ভাঙ্গন। সাধারণ ক্ষেত্রগুলিকে চিহ্নিত করা হয়েছে 'শিরোনাম', 'বিষয়বস্তু' এবং 'পাদচরণ'।

একটি পৃষ্ঠার অংশগুলি সনাক্ত করার পিছনে লক্ষ্য হল যে আমরা নেটওয়ার্কে না গিয়ে কী প্রিক্যাচ করা এবং পুনরুদ্ধার করা যেতে পারে তা নির্ধারণ করি—যেমন শিরোনাম এবং ফুটার মার্কআপ সমস্ত পৃষ্ঠাগুলিতে সাধারণ—এবং পৃষ্ঠার অংশ যা আমরা সর্বদা নেটওয়ার্কে যাব৷ প্রথম জন্য—এই ক্ষেত্রে বিষয়বস্তু।

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

তারপর, workbox-streams মাধ্যমে স্ট্রীমস API ব্যবহার করে, আমরা এই সমস্ত অংশগুলিকে একসাথে সেলাই করতে পারি এবং নেভিগেশন অনুরোধগুলির সাথে সাথেই প্রতিক্রিয়া জানাতে পারি — নেটওয়ার্ক থেকে প্রয়োজনীয় ন্যূনতম পরিমাণ মার্কআপের অনুরোধ করার সময়।

একটি স্ট্রিমিং পরিষেবা কর্মী তৈরি করা

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

আপনার ওয়েবসাইটকে আংশিক অংশে ভাগ করা

আপনি একটি স্ট্রিমিং পরিষেবা কর্মী লেখা শুরু করার আগে, আপনাকে তিনটি জিনিস করতে হবে:

  1. শুধুমাত্র আপনার ওয়েবসাইটের হেডার মার্কআপ ধারণকারী একটি ফাইল তৈরি করুন।
  2. শুধুমাত্র আপনার ওয়েবসাইটের ফুটার মার্কআপ ধারণকারী একটি ফাইল তৈরি করুন।
  3. প্রতিটি পৃষ্ঠার মূল বিষয়বস্তুকে একটি পৃথক ফাইলে টেনে আনুন, অথবা একটি HTTP অনুরোধ শিরোনামের উপর ভিত্তি করে শর্তসাপেক্ষে শুধুমাত্র পৃষ্ঠার বিষয়বস্তু পরিবেশন করতে আপনার পিছনের প্রান্তটি সেট আপ করুন৷

আপনি আশা করতে পারেন, শেষ ধাপটি সবচেয়ে কঠিন, বিশেষ করে যদি আপনার ওয়েবসাইটটি স্ট্যাটিক হয়। যদি আপনার ক্ষেত্রে এটি হয়, তাহলে আপনাকে প্রতিটি পৃষ্ঠার দুটি সংস্করণ তৈরি করতে হবে: একটি সংস্করণে সম্পূর্ণ পৃষ্ঠা মার্কআপ থাকবে, অন্যটিতে শুধুমাত্র সামগ্রী থাকবে৷

একটি স্ট্রিমিং পরিষেবা কর্মী রচনা

আপনি যদি workbox-streams মডিউলটি ইনস্টল না করে থাকেন, তবে আপনি বর্তমানে ইনস্টল করা ওয়ার্কবক্স মডিউলগুলি ছাড়াও আপনাকে এটি করতে হবে। এই নির্দিষ্ট উদাহরণের জন্য, এতে নিম্নলিখিত প্যাকেজগুলি জড়িত:

npm i workbox-navigation-preload workbox-strategies workbox-routing workbox-precaching workbox-streams --save

এখান থেকে, পরবর্তী ধাপ হল আপনার নতুন পরিষেবা কর্মী তৈরি করা এবং আপনার হেডার এবং ফুটার আংশিকগুলিকে প্রিক্যাচ করা।

প্রিক্যাচিং আংশিক

প্রথমে আপনি যা করবেন তা হল আপনার প্রকল্পের রুটে sw.js (অথবা আপনি যে ফাইলের নাম পছন্দ করেন) নামে একজন পরিষেবা কর্মী তৈরি করুন। এটিতে, আপনি নিম্নলিখিতগুলি দিয়ে শুরু করবেন:

// sw.js
import * as navigationPreload from 'workbox-navigation-preload';
import {NetworkFirst} from 'workbox-strategies';
import {registerRoute} from 'workbox-routing';
import {matchPrecache, precacheAndRoute} from 'workbox-precaching';
import {strategy as composeStrategies} from 'workbox-streams';

// Enable navigation preload for supporting browsers
navigationPreload.enable();

// Precache partials and some static assets
// using the InjectManifest method.
precacheAndRoute([
  // The header partial:
  {
    url: '/partial-header.php',
    revision: __PARTIAL_HEADER_HASH__
  },
  // The footer partial:
  {
    url: '/partial-footer.php',
    revision: __PARTIAL_FOOTER_HASH__
  },
  // The offline fallback:
  {
    url: '/offline.php',
    revision: __OFFLINE_FALLBACK_HASH__
  },
  ...self.__WB_MANIFEST
]);

// To be continued...

এই কোডটি কয়েকটি জিনিস করে:

  1. এটি সমর্থন করে এমন ব্রাউজারগুলির জন্য নেভিগেশন প্রিলোড সক্ষম করে৷
  2. শিরোনাম এবং ফুটার মার্কআপ প্রিক্যাচ করে। এর মানে হল যে প্রতিটি পৃষ্ঠার শিরোনাম এবং ফুটার মার্কআপ তাৎক্ষণিকভাবে পুনরুদ্ধার করা হবে, কারণ এটি নেটওয়ার্ক দ্বারা ব্লক করা হবে না।
  3. __WB_MANIFEST স্থানধারক যা injectManifest পদ্ধতি ব্যবহার করে স্ট্যাটিক সম্পদগুলিকে প্রিক্যাচ করে।

স্ট্রিমিং প্রতিক্রিয়া

আপনার পরিষেবা কর্মীকে সংযুক্ত প্রতিক্রিয়াগুলি স্ট্রিম করা এই পুরো প্রচেষ্টার সবচেয়ে বড় অংশ। তা সত্ত্বেও, ওয়ার্কবক্স এবং এর workbox-streams এটিকে অনেক বেশি সংক্ষিপ্ত বিষয় করে তোলে যদি আপনাকে নিজেরাই এই সমস্ত কিছু করতে হয়:

// sw.js
import * as navigationPreload from 'workbox-navigation-preload';
import {NetworkFirst} from 'workbox-strategies';
import {registerRoute} from 'workbox-routing';
import {matchPrecache, precacheAndRoute} from 'workbox-precaching';
import {strategy as composeStrategies} from 'workbox-streams';

// ...
// Prior navigation preload and precaching code omitted...
// ...

// The strategy for retrieving content partials from the network:
const contentStrategy = new NetworkFirst({
  cacheName: 'content',
  plugins: [
    {
      // NOTE: This callback will never be run if navigation
      // preload is not supported, because the navigation
      // request is dispatched while the service worker is
      // booting up. This callback will only run if navigation
      // preload is _not_ supported.
      requestWillFetch: ({request}) => {
        const headers = new Headers();

        // If the browser doesn't support navigation preload, we need to
        // send a custom `X-Content-Mode` header for the back end to use
        // instead of the `Service-Worker-Navigation-Preload` header.
        headers.append('X-Content-Mode', 'partial');

        // Send the request with the new headers.
        // Note: if you're using a static site generator to generate
        // both full pages and content partials rather than a back end
        // (as this example assumes), you'll need to point to a new URL.
        return new Request(request.url, {
          method: 'GET',
          headers
        });
      },
      // What to do if the request fails.
      handlerDidError: async ({request}) => {
        return await matchPrecache('/offline.php');
      }
    }
  ]
});

// Concatenates precached partials with the content partial
// obtained from the network (or its fallback response).
const navigationHandler = composeStrategies([
  // Get the precached header markup.
  () => matchPrecache('/partial-header.php'),
  // Get the content partial from the network.
  ({event}) => contentStrategy.handle(event),
  // Get the precached footer markup.
  () => matchPrecache('/partial-footer.php')
]);

// Register the streaming route for all navigation requests.
registerRoute(({request}) => request.mode === 'navigate', navigationHandler);

// Your service worker can end here, or you can add more
// logic to suit your needs, such as runtime caching, etc.

এই কোডটি তিনটি প্রধান অংশ নিয়ে গঠিত যা নিম্নলিখিত প্রয়োজনীয়তাগুলি পূরণ করে:

  1. একটি NetworkFirst কৌশল সামগ্রী আংশিকগুলির জন্য অনুরোধগুলি পরিচালনা করতে ব্যবহৃত হয়। এই কৌশলটি ব্যবহার করে, content একটি কাস্টম ক্যাশ নাম নির্দিষ্ট করা হয় যাতে বিষয়বস্তুর আংশিক থাকে, সেইসাথে একটি কাস্টম প্লাগইন যা পরিচালনা করে যে ব্রাউজারগুলির জন্য একটি X-Content-Mode অনুরোধ শিরোনাম সেট করা হবে কিনা যা নেভিগেশন প্রিলোড সমর্থন করে না (এবং তাই ডন একটি Service-Worker-Navigation-Preload শিরোনাম পাঠাবেন না)। এই প্লাগইনটি আংশিক বিষয়বস্তুর শেষ ক্যাশে করা সংস্করণটি পাঠাতে হবে কিনা বা বর্তমান অনুরোধের জন্য কোনও ক্যাশে করা সংস্করণ সংরক্ষণ না করার ক্ষেত্রে একটি অফলাইন ফলব্যাক পৃষ্ঠা পাঠাতে হবে কিনা তাও নির্ধারণ করে৷
  2. workbox-streams strategy পদ্ধতি (এখানে composeStrategies নামে পরিচিত) নেটওয়ার্ক থেকে অনুরোধ করা বিষয়বস্তুর সাথে প্রিক্যাচেড হেডার এবং ফুটার আংশিকগুলিকে সংযুক্ত করতে ব্যবহৃত হয়।
  3. পুরো স্কিমটি নেভিগেশন অনুরোধের জন্য registerRoute মাধ্যমে তৈরি করা হয়েছে।

এই যুক্তির সাথে, আমরা স্ট্রিমিং প্রতিক্রিয়া সেট আপ করেছি। যাইহোক, নেটওয়ার্কের বিষয়বস্তু একটি আংশিক পৃষ্ঠা যা আপনি প্রিক্যাচেড আংশিকগুলির সাথে একত্রিত করতে পারেন তা নিশ্চিত করার জন্য আপনাকে পিছনের দিকে কিছু কাজ করতে হবে।

আপনার ওয়েবসাইট একটি পিছনে শেষ আছে

আপনি মনে রাখবেন যে যখন নেভিগেশন প্রিলোড সক্ষম করা হয়, তখন ব্রাউজার একটি Service-Worker-Navigation-Preload হেডার পাঠায় যার মান true । যাইহোক, উপরের কোড নমুনায়, আমরা ইভেন্ট নেভিগেশন প্রিলোড ব্রাউজারে অসমর্থিত X-Content-Mode একটি কাস্টম হেডার পাঠিয়েছি। পিছনের শেষে, আপনি এই শিরোনামগুলির উপস্থিতির উপর ভিত্তি করে প্রতিক্রিয়া পরিবর্তন করবেন। একটি পিএইচপি ব্যাক এন্ডে, এটি একটি প্রদত্ত পৃষ্ঠার জন্য এরকম কিছু দেখতে পারে:

<?php
// Check if we need to render a content partial
$navPreloadSupported = isset($_SERVER['HTTP_SERVICE_WORKER_NAVIGATION_PRELOAD']) && $_SERVER['HTTP_SERVICE_WORKER_NAVIGATION_PRELOAD'] === 'true';
$partialContentMode = isset($_SERVER['HTTP_X_CONTENT_MODE']) && $_SERVER['HTTP_X_CONTENT_MODE'] === 'partial';
$isPartial = $navPreloadSupported || $partialContentMode;

// Figure out whether to render the header
if ($isPartial === false) {
  // Get the header include
  require_once($_SERVER['DOCUMENT_ROOT'] . '/includes/site-header.php');

  // Render the header
  siteHeader();
}

// Get the content include
require_once('./content.php');

// Render the content
content($isPartial);

// Figure out whether to render the footer
if ($isPartial === false) {
  // Get the footer include
  require_once($_SERVER['DOCUMENT_ROOT'] . '/includes/site-footer.php');

  // Render the footer
  siteFooter();
}
?>

উপরের উদাহরণে, বিষয়বস্তু আংশিকগুলিকে ফাংশন হিসাবে আহ্বান করা হয়েছে, যা $isPartial এর মান নেয় আংশিকগুলি কীভাবে রেন্ডার করা হয় তা পরিবর্তন করতে। উদাহরণস্বরূপ, content রেন্ডারার ফাংশন শুধুমাত্র কিছু নির্দিষ্ট মার্কআপ অন্তর্ভুক্ত করতে পারে যখন একটি আংশিক হিসাবে পুনরুদ্ধার করা হয় - যা শীঘ্রই কভার করা হবে।

বিবেচনা

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

নেভিগেট করার সময় পৃষ্ঠার উপাদান আপডেট করা

এই পদ্ধতির সবচেয়ে জটিল অংশ হল যে কিছু জিনিস ক্লায়েন্টে আপডেট করা প্রয়োজন। উদাহরণ স্বরূপ, হেডার মার্কআপ প্রিক্যাচ করার অর্থ হল <title> এলিমেন্টে পৃষ্ঠার একই বিষয়বস্তু থাকবে, অথবা এমনকি নেভিগেশন আইটেমগুলির জন্য চালু/বন্ধ অবস্থাগুলি পরিচালনা করা প্রতিটি নেভিগেশনে আপডেট করতে হবে। প্রতিটি নেভিগেশন অনুরোধের জন্য এই জিনিসগুলি-এবং অন্যান্যগুলি-কে ক্লায়েন্টে আপডেট করতে হতে পারে।

এটির কাছাকাছি যাওয়ার উপায় হল কিছু গুরুত্বপূর্ণ বিষয় আপডেট করার জন্য নেটওয়ার্ক থেকে আসা সামগ্রীর আংশিক অংশে একটি ইনলাইন <script> উপাদান স্থাপন করা:

<!-- The JSON below contains information about the current page. -->
<script id="page-data" type="application/json">'{"title":"Sand Wasp &mdash; World of Wasps","description":"Read all about the sand wasp in this tidy little post."}'</script>
<script>
  const pageData = JSON.parse(document.getElementById('page-data').textContent);

  // Update the page title
  document.title = pageData.title;
</script>
<article>
  <!-- Page content omitted... -->
</article>

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

ধীরগতির নেটওয়ার্ক নিয়ে কাজ করা

নেটওয়ার্ক সংযোগগুলি ধীর হলে precache থেকে মার্কআপ ব্যবহার করে স্ট্রিমিং প্রতিক্রিয়াগুলির একটি ত্রুটি ঘটতে পারে৷ সমস্যা হল যে precache থেকে হেডার মার্কআপ তাৎক্ষণিকভাবে আসবে, কিন্তু নেটওয়ার্ক থেকে আংশিক বিষয়বস্তু হেডার মার্কআপের প্রাথমিক পেইন্টের পরে আসতে বেশ কিছু সময় নিতে পারে।

এটি একটি বিভ্রান্তিকর অভিজ্ঞতার কিছু তৈরি করতে পারে, এবং যদি নেটওয়ার্কগুলি খুব ধীর হয়, তাহলে এটি এমনকি মনে হতে পারে যে পৃষ্ঠাটি ভেঙে গেছে এবং আর রেন্ডার হচ্ছে না। এই ধরনের ক্ষেত্রে, আপনি বিষয়বস্তুর আংশিক মার্কআপে একটি লোডিং আইকন বা বার্তা রাখতে বেছে নিতে পারেন যা একবার সামগ্রী লোড হয়ে গেলে আপনি লুকাতে পারেন৷

এটি করার একটি উপায় হল CSS এর মাধ্যমে। বলুন আপনার শিরোনাম আংশিকটি একটি খোলার <article> উপাদান দিয়ে শেষ হয় যা খালি থাকে যতক্ষণ না বিষয়বস্তু আংশিক এটিকে পপুলেট করতে আসে। আপনি এই অনুরূপ একটি CSS নিয়ম লিখতে পারেন:

article:empty::before {
  text-align: center;
  content: 'Loading...';
}

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

.slow article:empty::before {
  text-align: center;
  content: 'Loading...';
}

এখান থেকে আপনি আপনার হেডারে আংশিক জাভাস্ক্রিপ্ট ব্যবহার করে কার্যকর সংযোগের ধরন পড়তে পারেন (অন্তত ক্রোমিয়াম ব্রাউজারে) <html> এলিমেন্টে slow ক্লাস যোগ করার জন্য নির্বাচিত সংযোগের ধরনগুলিতে:

<script>
  const effectiveType = navigator?.connection?.effectiveType;

  if (effectiveType !== '4g') {
    document.documentElement.classList.add('slow');
  }
</script>

এটি নিশ্চিত করবে যে কার্যকর সংযোগের ধরনগুলি 4g টাইপের চেয়ে ধীর গতিতে একটি লোডিং বার্তা পাবে৷ তারপর আংশিক বিষয়বস্তুতে, লোডিং বার্তা থেকে পরিত্রাণ পেতে HTML থেকে slow শ্রেণীটি সরাতে আপনি একটি ইনলাইন <script> উপাদান রাখতে পারেন:

<script>
  document.documentElement.classList.remove('slow');
</script>

একটি ফলব্যাক প্রতিক্রিয়া প্রদান

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

একটি ফলব্যাক প্রতিক্রিয়া অর্জনের জন্য প্রয়োজনীয় কোডটি পূর্বের কোড নমুনাগুলিতে প্রদর্শিত হয়। প্রক্রিয়াটির দুটি ধাপ প্রয়োজন:

  1. একটি অফলাইন ফলব্যাক প্রতিক্রিয়া precache.
  2. একটি পৃষ্ঠার সর্বশেষ-অ্যাক্সেস করা সংস্করণের জন্য ক্যাশে চেক করতে আপনার নেটওয়ার্ক-প্রথম কৌশলটির জন্য প্লাগইনে একটি handlerDidError কলব্যাক সেট আপ করুন৷ যদি পৃষ্ঠাটি কখনই অ্যাক্সেস করা না হয়, তাহলে আপনাকে precache থেকে ফলব্যাক প্রতিক্রিয়া পুনরুদ্ধার করতে workbox-precaching মডিউল থেকে matchPrecache পদ্ধতি ব্যবহার করতে হবে।

ক্যাশিং এবং সিডিএন

আপনি যদি আপনার পরিষেবা কর্মীতে এই স্ট্রিমিং প্যাটার্নটি ব্যবহার করে থাকেন তবে নিম্নলিখিতগুলি আপনার পরিস্থিতিতে প্রযোজ্য কিনা তা মূল্যায়ন করুন:

  • আপনি একটি CDN বা অন্য কোনো ধরনের মধ্যবর্তী/পাবলিক ক্যাশে ব্যবহার করেন।
  • আপনি একটি Cache-Control শিরোনাম নির্দিষ্ট করেছেন একটি নন-জিরো max-age এবং/অথবা s-maxage নির্দেশিকা(গুলি) public নির্দেশের সাথে সমন্বয় করে।

যদি এই দুটিই আপনার ক্ষেত্রে হয়, তাহলে মধ্যবর্তী ক্যাশে নেভিগেশন অনুরোধের প্রতিক্রিয়া ধরে রাখতে পারে। যাইহোক, মনে রাখবেন যে আপনি যখন এই প্যাটার্নটি ব্যবহার করেন, আপনি যেকোন ইউআরএলের জন্য দুটি ভিন্ন প্রতিক্রিয়া পরিবেশন করতে পারেন:

  • শিরোনাম, বিষয়বস্তু এবং ফুটার মার্কআপ সহ সম্পূর্ণ প্রতিক্রিয়া।
  • আংশিক প্রতিক্রিয়া, শুধুমাত্র বিষয়বস্তু ধারণকারী.

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

এটির কাছাকাছি পেতে, আপনাকে Vary হেডারের উপর নির্ভর করতে হবে, যা অনুরোধে উপস্থিত এক বা একাধিক শিরোলেখের ক্যাশেযোগ্য প্রতিক্রিয়াগুলি কী করে ক্যাশিং আচরণকে প্রভাবিত করে৷ যেহেতু আমরা Service-Worker-Navigation-Preload এবং কাস্টম X-Content-Mode অনুরোধ শিরোনামের উপর ভিত্তি করে নেভিগেশন অনুরোধের প্রতিক্রিয়ার পরিবর্তন করছি, তাই আমাদের প্রতিক্রিয়াতে এই Vary শিরোনামটি নির্দিষ্ট করতে হবে:

Vary: Service-Worker-Navigation-Preload,X-Content-Mode

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

ফলাফল

বেশিরভাগ লোড-টাইম পারফরম্যান্স পরামর্শ "আপনি যা পেয়েছেন তা দেখান" - পিছিয়ে থাকবেন না, ব্যবহারকারীকে কিছু দেখানোর আগে আপনার কাছে সবকিছু না হওয়া পর্যন্ত অপেক্ষা করবেন না।

দ্রুত কন্টেন্টের জন্য ফান হ্যাকসে জেক আর্চিবাল্ড

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

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

  • টাইম টু ফার্স্ট বাইট (TTFB) প্রায়ই অনেক কমে যাবে, কারণ একটি নেভিগেশন অনুরোধের প্রতিক্রিয়ার প্রথম বাইট তাৎক্ষণিক।
  • ফার্স্ট কনটেন্টফুল পেইন্ট (FCP) খুব দ্রুত হবে, কারণ প্রিক্যাচেড হেডার মার্কআপে একটি ক্যাশে করা স্টাইল শীটের একটি রেফারেন্স থাকবে, যার অর্থ পৃষ্ঠাটি খুব দ্রুত পেইন্ট করবে।
  • কিছু ক্ষেত্রে, লার্জেস্ট কনটেন্টফুল পেইন্ট (LCP) দ্রুততর হতে পারে, বিশেষ করে যদি প্রিক্যাচড হেডার আংশিক দ্বারা সবচেয়ে বড় অনস্ক্রিন উপাদান প্রদান করা হয়। তা সত্ত্বেও, যত তাড়াতাড়ি সম্ভব পরিষেবা কর্মী ক্যাশের বাইরে কিছু পরিবেশন করলে ছোট মার্কআপ পেলোডের সাথে একটি ভাল LCP হতে পারে।

স্ট্রিমিং মাল্টিপেজ আর্কিটেকচারগুলি সেট আপ করা এবং পুনরাবৃত্তি করা কিছুটা কঠিন হতে পারে, তবে জড়িত জটিলতা প্রায়শই তত্ত্বের ক্ষেত্রে এসপিএগুলির চেয়ে বেশি কঠিন নয়। প্রধান সুবিধা হল আপনি ব্রাউজারের ডিফল্ট নেভিগেশন স্কিম প্রতিস্থাপন করছেন না-আপনি এটিকে উন্নত করছেন

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

সম্পদ