SPA-এর বাইরে - আপনার PWA এর জন্য বিকল্প আর্কিটেকচার

আসুন... স্থাপত্যের কথা বলি?

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

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

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

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

স্ট্যাক ওভারফ্লো PWA

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

মাল্টি-পেজ অ্যাপস (এমপিএ)

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

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

এটি ওয়েব অ্যাপ তৈরির জন্য একক-পৃষ্ঠা অ্যাপ (SPA) মডেলের বিপরীতে, যেখানে ব্রাউজার জাভাস্ক্রিপ্ট কোড চালায় বর্তমান পৃষ্ঠা আপডেট করার জন্য যখন ব্যবহারকারী একটি নতুন বিভাগে যান। SPA এবং MPA উভয়ই ব্যবহার করার জন্য সমানভাবে বৈধ মডেল, কিন্তু এই পোস্টের জন্য, আমি একটি বহু-পৃষ্ঠা অ্যাপের প্রেক্ষাপটে PWA ধারণাগুলি অন্বেষণ করতে চেয়েছিলাম।

নির্ভরযোগ্যভাবে দ্রুত

আপনি আমাকে (এবং অগণিত অন্যান্য) শব্দগুচ্ছ "প্রগতিশীল ওয়েব অ্যাপ", বা PWA ব্যবহার করতে শুনেছেন। আপনি হয়তো ইতিমধ্যেই এই সাইটের অন্য কোথাও পটভূমির কিছু উপাদানের সাথে পরিচিত।

আপনি একটি PWA কে একটি ওয়েব অ্যাপ হিসাবে ভাবতে পারেন যা একটি প্রথম শ্রেণীর ব্যবহারকারীর অভিজ্ঞতা প্রদান করে এবং এটি ব্যবহারকারীর হোম স্ক্রিনে সত্যিই একটি স্থান অর্জন করে। সংক্ষিপ্ত রূপ " FIRE " , F ast , I integrated , R eliable , এবং E ngaging , PWA তৈরি করার সময় চিন্তা করার জন্য সমস্ত বৈশিষ্ট্যের যোগফল দেয়৷

এই নিবন্ধে, আমি সেই বৈশিষ্ট্যগুলির একটি উপসেটের উপর ফোকাস করতে যাচ্ছি: দ্রুত এবং নির্ভরযোগ্য

দ্রুত: যদিও "দ্রুত" অর্থ বিভিন্ন প্রসঙ্গে বিভিন্ন জিনিস, আমি নেটওয়ার্ক থেকে যতটা সম্ভব কম লোড করার গতির সুবিধাগুলি কভার করতে যাচ্ছি।

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

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

প্রযুক্তি সক্ষম করা: পরিষেবা কর্মী + ক্যাশে স্টোরেজ API

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

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

নেটওয়ার্ক প্রতিক্রিয়ার একটি অনুলিপি সংরক্ষণ করতে ক্যাশে স্টোরেজ API ব্যবহার করে একজন পরিষেবা কর্মী৷

পরের বার যখন ওয়েব অ্যাপটি একই অনুরোধ করে, তখন তার পরিষেবা কর্মী তার ক্যাশে চেক করতে পারে এবং পূর্বে ক্যাশে করা প্রতিক্রিয়াটি ফিরিয়ে দিতে পারে।

নেটওয়ার্ক বাইপাস করে প্রতিক্রিয়া জানাতে ক্যাশে স্টোরেজ API ব্যবহার করে একজন পরিষেবা কর্মী।

যখনই সম্ভব নেটওয়ার্ক এড়িয়ে চলা নির্ভরযোগ্যভাবে দ্রুত কর্মক্ষমতা প্রদানের একটি গুরুত্বপূর্ণ অংশ।

"আইসোমরফিক" জাভাস্ক্রিপ্ট

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

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

সার্ভার

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

আমি স্ট্যাটিক হোস্টিং সহ একটি গতিশীল ব্যাকএন্ডের সংমিশ্রণ খুঁজছিলাম, এবং আমার পদ্ধতি ছিল ফায়ারবেস প্ল্যাটফর্ম ব্যবহার করা।

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

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

একটি নেভিগেশন প্রতিক্রিয়া তৈরির একটি ওভারভিউ, সার্ভার-সাইড।

সার্ভার URL-এর উপর ভিত্তি করে অনুরোধটি রুট করে এবং একটি সম্পূর্ণ HTML নথি তৈরি করতে টেমপ্লেটিং লজিক ব্যবহার করে। আমি স্ট্যাক এক্সচেঞ্জ API থেকে ডেটার সংমিশ্রণ ব্যবহার করি, সেইসাথে আংশিক এইচটিএমএল টুকরা যা সার্ভার স্থানীয়ভাবে সঞ্চয় করে। একবার আমাদের পরিষেবা কর্মী কীভাবে প্রতিক্রিয়া জানাতে হয় তা জানলে, এটি আমাদের ওয়েব অ্যাপে এইচটিএমএল স্ট্রিমিং শুরু করতে পারে।

আরও বিস্তারিতভাবে অন্বেষণ করার মতো এই ছবির দুটি অংশ রয়েছে: রাউটিং এবং টেমপ্লেটিং।

রাউটিং

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

const routes = new Map([
  ['about', '/about'],
  ['questions', '/questions/:questionId'],
  ['index', '/'],
]);

export default routes;

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

import routes from './lib/routes.mjs';
app.get(routes.get('index'), async (req, res) => {
  // Templating logic.
});

সার্ভার-সাইড টেমপ্লেটিং

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

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

আমি কী বলতে চাইছি তা দেখতে, আমাদের রুটের একটির জন্য এক্সপ্রেস কোডটি দেখুন:

app.get(routes.get('index'), async (req, res) => {
  res.write(headPartial + navbarPartial);
  const tag = req.query.tag || DEFAULT_TAG;
  const data = await requestData(...);
  res.write(templates.index(tag, data.items));
  res.write(footPartial);
  res.end();
});

response অবজেক্টের write() পদ্ধতি ব্যবহার করে এবং স্থানীয়ভাবে সঞ্চিত আংশিক টেমপ্লেট উল্লেখ করে, আমি কোনো বাহ্যিক ডেটা উৎস ব্লক না করে অবিলম্বে প্রতিক্রিয়া স্ট্রীম শুরু করতে পারি। ব্রাউজারটি এই প্রাথমিক এইচটিএমএলটি নেয় এবং একটি অর্থপূর্ণ ইন্টারফেস এবং লোডিং বার্তা রেন্ডার করে।

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

ওয়েব অ্যাপটি স্ট্যাক এক্সচেঞ্জ API থেকে প্রতিক্রিয়া পাওয়ার পরে, এটি API থেকে ডেটাকে তার সংশ্লিষ্ট HTML-এ অনুবাদ করার জন্য একটি কাস্টম টেমপ্লেটিং ফাংশনকে কল করে।

টেমপ্লেটিং ভাষা

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

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

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

export function index(tag, items) {
  const title = `<h3>Top "${escape(tag)}" Questions</h3>`;
  const form = `<form method="GET">...</form>`;
  const questionCards = items
    .map(item =>
      questionCard({
        id: item.question_id,
        title: item.title,
      })
    )
    .join('');
  const questions = `<div id="questions">${questionCards}</div>`;
  return title + form + questions;
}

এই টেমপ্লেট ফাংশনগুলি খাঁটি জাভাস্ক্রিপ্ট, এবং যথোপযুক্ত হলে যুক্তিটিকে ছোট, সহায়ক ফাংশনে বিভক্ত করা দরকারী। এখানে, আমি API প্রতিক্রিয়ায় ফিরে আসা প্রতিটি আইটেমকে এমন একটি ফাংশনে পাস করি, যা সমস্ত উপযুক্ত বৈশিষ্ট্য সেট সহ একটি আদর্শ HTML উপাদান তৈরি করে।

function questionCard({id, title}) {
  return `<a class="card"
             href="/questions/${id}"
             data-cache-url="${questionUrl(id)}">${title}</a>`;
}

বিশেষ নোট হল একটি ডেটা অ্যাট্রিবিউট যা আমি প্রতিটি লিঙ্কে যোগ করি, data-cache-url , স্ট্যাক এক্সচেঞ্জ API URL-এ সেট করা যা সংশ্লিষ্ট প্রশ্নটি প্রদর্শন করার জন্য আমার প্রয়োজন। মন যে রাখতে. আমি পরে এটা পুনর্বিবেচনা করব.

আমার রুট হ্যান্ডলারে ফিরে গিয়ে, টেমপ্লেটিং সম্পূর্ণ হলে, আমি আমার পৃষ্ঠার HTML এর চূড়ান্ত অংশ ব্রাউজারে স্ট্রিম করি এবং স্ট্রীমটি শেষ করি। এটি ব্রাউজারটির সংকেত যে প্রগতিশীল রেন্ডারিং সম্পূর্ণ হয়েছে।

app.get(routes.get('index'), async (req, res) => {
  res.write(headPartial + navbarPartial);
  const tag = req.query.tag || DEFAULT_TAG;
  const data = await requestData(...);
  res.write(templates.index(tag, data.items));
  res.write(footPartial);
  res.end();
});

তাই যে আমার সার্ভার সেটআপ একটি সংক্ষিপ্ত সফর. যে ব্যবহারকারীরা প্রথমবারের জন্য আমার ওয়েব অ্যাপে যান তারা সর্বদা সার্ভার থেকে একটি প্রতিক্রিয়া পাবেন, কিন্তু যখন একজন দর্শক আমার ওয়েব অ্যাপে ফিরে আসবে, তখন আমার পরিষেবা কর্মী সাড়া দেওয়া শুরু করবে। এর সেখানে ডুব দেওয়া যাক.

সেবা কর্মী

পরিষেবা কর্মীর মধ্যে একটি নেভিগেশন প্রতিক্রিয়া তৈরি করার একটি ওভারভিউ।

এই ডায়াগ্রামটি পরিচিত হওয়া উচিত — আমি পূর্বে কভার করেছি একই টুকরাগুলির মধ্যে অনেকগুলি এখানে একটু ভিন্ন বিন্যাসে রয়েছে। পরিষেবা কর্মীকে বিবেচনায় নিয়ে অনুরোধের প্রবাহের মধ্য দিয়ে চলুন।

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

পদ্ধতিটি আগের মতোই, তবে বিভিন্ন নিম্ন-স্তরের আদিম, যেমন fetch() এবং ক্যাশে স্টোরেজ API সহ। আমি HTML প্রতিক্রিয়া তৈরি করতে সেই ডেটা উত্সগুলি ব্যবহার করি, যা পরিষেবা কর্মী ওয়েব অ্যাপে ফেরত দেয়৷

ওয়ার্কবক্স

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

রাউটিং

ঠিক যেমন আমার সার্ভার-সাইড কোডের সাথে, আমার পরিষেবা কর্মীকে জানতে হবে কিভাবে উপযুক্ত প্রতিক্রিয়া যুক্তির সাথে একটি ইনকামিং অনুরোধের সাথে মেলে।

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

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

import regExpRoutes from './regexp-routes.mjs';

workbox.routing.registerRoute(
  regExpRoutes.get('index')
  // Templating logic.
);

স্ট্যাটিক সম্পদ ক্যাশিং

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

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

module.exports = {
  globDirectory: 'build',
  globPatterns: ['**/*.{html,js,svg}'],
  // Other options...
};

ওয়ার্কবক্স প্রতিটি ফাইলের বিষয়বস্তুর একটি স্ন্যাপশট নেয় এবং স্বয়ংক্রিয়ভাবে আমার চূড়ান্ত পরিষেবা কর্মী ফাইলে URL এবং সংশোধনগুলির তালিকাটি ইনজেক্ট করে। ওয়ার্কবক্সে এখন প্রিক্যাচ করা ফাইলগুলিকে সর্বদা উপলব্ধ করতে এবং আপ টু ডেট রাখার জন্য প্রয়োজনীয় সবকিছু রয়েছে৷ ফলাফল হল একটি service-worker.js ফাইল যা নিম্নলিখিত অনুরূপ কিছু ধারণ করে:

workbox.precaching.precacheAndRoute([
  {
    url: 'partials/about.html',
    revision: '518747aad9d7e',
  },
  {
    url: 'partials/foot.html',
    revision: '69bf746a9ecc6',
  },
  // etc.
]);

যারা আরও জটিল বিল্ড প্রক্রিয়া ব্যবহার করেন তাদের জন্য, ওয়ার্কবক্সের কমান্ড লাইন ইন্টারফেস ছাড়াও একটি webpack প্লাগইন এবং একটি জেনেরিক নোড মডিউল উভয়ই রয়েছে।

স্ট্রিমিং

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

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

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

ঠিক আছে... একটি জিনিস আপনাকে থামাতে পারে, এবং এটি স্ট্রিম এপিআই আসলে কীভাবে কাজ করে তার চারপাশে আপনার মাথা মোড়ানো। এটি প্রিমটিভের একটি খুব শক্তিশালী সেট প্রকাশ করে, এবং বিকাশকারীরা যারা এটি ব্যবহার করতে স্বাচ্ছন্দ্য বোধ করে তারা জটিল ডেটা প্রবাহ তৈরি করতে পারে, যেমন:

const stream = new ReadableStream({
  pull(controller) {
    return sources[0]
      .then(r => r.read())
      .then(result => {
        if (result.done) {
          sources.shift();
          if (sources.length === 0) return controller.close();
          return this.pull(controller);
        } else {
          controller.enqueue(result.value);
        }
      });
  },
});

কিন্তু এই কোডের সম্পূর্ণ প্রভাব বোঝা সবার জন্য নাও হতে পারে। এই যুক্তির মাধ্যমে পার্স করার পরিবর্তে, আসুন পরিষেবা কর্মী স্ট্রিমিং সম্পর্কে আমার পদ্ধতি সম্পর্কে কথা বলি।

আমি একটি একেবারে নতুন, উচ্চ-স্তরের মোড়ক, workbox-streams ব্যবহার করছি। এটির সাহায্যে, আমি এটিকে স্ট্রিমিং উত্সগুলির মিশ্রণে পাস করতে পারি, উভয় ক্যাশে এবং রানটাইম ডেটা যা নেটওয়ার্ক থেকে আসতে পারে। ওয়ার্কবক্স পৃথক উত্সগুলির সমন্বয় সাধনের যত্ন নেয় এবং সেগুলিকে একক, স্ট্রিমিং প্রতিক্রিয়াতে একসাথে সেলাই করে।

অতিরিক্তভাবে, ওয়ার্কবক্স স্বয়ংক্রিয়ভাবে সনাক্ত করে যে স্ট্রিম API সমর্থিত কিনা, এবং যখন এটি না হয়, এটি একটি সমতুল্য, অ-স্ট্রিমিং প্রতিক্রিয়া তৈরি করে। এর মানে হল যে আপনাকে ফলব্যাক লেখার বিষয়ে চিন্তা করতে হবে না, কারণ স্ট্রীমগুলি 100% ব্রাউজার সমর্থনের কাছাকাছি।

রানটাইম ক্যাশিং

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

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

const cacheStrategy = workbox.strategies.cacheFirst({
  cacheName: workbox.core.cacheNames.precache,
});

const apiStrategy = workbox.strategies.staleWhileRevalidate({
  cacheName: API_CACHE_NAME,
  plugins: [new workbox.expiration.Plugin({maxEntries: 50})],
});

প্রথম কৌশলটি আমাদের আংশিক এইচটিএমএল টেমপ্লেটগুলির মতো প্রিক্যাচ করা ডেটা পড়ে।

অন্য কৌশলটি 50টি এন্ট্রিতে পৌঁছানোর পর ন্যূনতম-সম্প্রতি-ব্যবহৃত ক্যাশের মেয়াদ শেষ হওয়ার সাথে সাথে stale-while-revalidate caching লজিক প্রয়োগ করে।

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

workbox.streams.strategy([
  () => cacheStrategy.makeRequest({request: '/head.html'}),
  () => cacheStrategy.makeRequest({request: '/navbar.html'}),
  async ({event, url}) => {
    const tag = url.searchParams.get('tag') || DEFAULT_TAG;
    const listResponse = await apiStrategy.makeRequest(...);
    const data = await listResponse.json();
    return templates.index(tag, data.items);
  },
  () => cacheStrategy.makeRequest({request: '/foot.html'}),
]);

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

আমাদের পরবর্তী সোর্স ফাংশন স্ট্যাক এক্সচেঞ্জ API থেকে ডেটা আনে এবং HTML-এ প্রতিক্রিয়া প্রক্রিয়া করে যা ওয়েব অ্যাপ আশা করে।

stale-while-revalidate কৌশলটির মানে হল যে যদি আমার কাছে এই API কলের জন্য পূর্বে ক্যাশে করা প্রতিক্রিয়া থাকে, তাহলে আমি তা অবিলম্বে পৃষ্ঠায় স্ট্রিম করতে সক্ষম হব, যখন পরের বার অনুরোধ করা হবে তখন "পটভূমিতে" ক্যাশে এন্ট্রি আপডেট করার সময় .

অবশেষে, আমি আমার ফুটারের একটি ক্যাশড কপি স্ট্রিম করি এবং প্রতিক্রিয়া সম্পূর্ণ করতে চূড়ান্ত HTML ট্যাগগুলি বন্ধ করি।

শেয়ারিং কোড জিনিসগুলিকে সিঙ্কে রাখে৷

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

গতিশীল, প্রগতিশীল উন্নতি

আমি আমার PWA-এর জন্য সার্ভার এবং পরিষেবা কর্মী উভয়ের মধ্য দিয়ে হেঁটেছি, কিন্তু কভার করার জন্য একটি শেষ বিট যুক্তি আছে: আমার প্রতিটি পৃষ্ঠায় অল্প পরিমাণে জাভাস্ক্রিপ্ট চলে, সেগুলি সম্পূর্ণরূপে স্ট্রিম করার পরে।

এই কোডটি ক্রমান্বয়ে ব্যবহারকারীর অভিজ্ঞতা বাড়ায়, কিন্তু গুরুত্বপূর্ণ নয়—ওয়েব অ্যাপটি কাজ করবে যদি এটি না চালানো হয়।

পৃষ্ঠা মেটাডেটা

API প্রতিক্রিয়ার উপর ভিত্তি করে একটি পৃষ্ঠার মেটাডেটা আপডেট করার জন্য আমার অ্যাপটি ক্লায়েন্ট-সাইড JavaScipt ব্যবহার করে। যেহেতু আমি প্রতিটি পৃষ্ঠার জন্য ক্যাশে করা HTML এর একই প্রাথমিক বিট ব্যবহার করি, ওয়েব অ্যাপটি আমার নথির মাথায় জেনেরিক ট্যাগ দিয়ে শেষ হয়। কিন্তু আমার টেমপ্লেটিং এবং ক্লায়েন্ট-সাইড কোডের মধ্যে সমন্বয়ের মাধ্যমে, আমি পৃষ্ঠা-নির্দিষ্ট মেটাডেটা ব্যবহার করে উইন্ডোর শিরোনাম আপডেট করতে পারি।

টেমপ্লেটিং কোডের অংশ হিসাবে, আমার পদ্ধতি হল একটি স্ক্রিপ্ট ট্যাগ অন্তর্ভুক্ত করা যাতে সঠিকভাবে পালিয়ে যাওয়া স্ট্রিং থাকে।

const metadataScript = `<script>
  self._title = '${escape(item.title)}';
</script>`;

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

if (self._title) {
  document.title = unescape(self._title);
}

যদি পৃষ্ঠা-নির্দিষ্ট মেটাডেটার অন্যান্য অংশ থাকে যা আপনি নিজের ওয়েব অ্যাপে আপডেট করতে চান, আপনি একই পদ্ধতি অনুসরণ করতে পারেন।

অফলাইন ইউএক্স

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

প্রথমত, আমি পূর্বে ক্যাশে করা সমস্ত API অনুরোধের একটি তালিকা পেতে ক্যাশে স্টোরেজ API ব্যবহার করি এবং আমি সেটিকে URL-এর তালিকায় অনুবাদ করি।

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

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

const apiCache = await caches.open(API_CACHE_NAME);
const cachedRequests = await apiCache.keys();
const cachedUrls = cachedRequests.map(request => request.url);

const cards = document.querySelectorAll('.card');
const uncachedCards = [...cards].filter(card => {
  return !cachedUrls.includes(card.dataset.cacheUrl);
});

const offlineHandler = () => {
  for (const uncachedCard of uncachedCards) {
    uncachedCard.style.opacity = '0.3';
  }
};

const onlineHandler = () => {
  for (const uncachedCard of uncachedCards) {
    uncachedCard.style.opacity = '1.0';
  }
};

window.addEventListener('online', onlineHandler);
window.addEventListener('offline', offlineHandler);

সাধারণ ক্ষতি

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

আপনার নিজস্ব স্থাপত্য সিদ্ধান্ত নেওয়ার সময় আপনি যে কয়েকটি সাধারণ ত্রুটির সম্মুখীন হতে পারেন এবং আমি আপনাকে কিছু ব্যথা বাঁচাতে চাই।

সম্পূর্ণ HTML ক্যাশে করবেন না

আমি আপনার ক্যাশে সম্পূর্ণ HTML নথি সংরক্ষণ করার বিরুদ্ধে সুপারিশ. এক জিনিসের জন্য, এটি স্থানের অপচয়। যদি আপনার ওয়েব অ্যাপ তার প্রতিটি পৃষ্ঠার জন্য একই মৌলিক HTML কাঠামো ব্যবহার করে, তাহলে আপনি একই মার্কআপের কপি বারবার সংরক্ষণ করতে পারবেন।

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

সার্ভার / সেবা কর্মী প্রবাহ

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

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

সবচেয়ে খারাপ পরিস্থিতি

অসামঞ্জস্যপূর্ণ বিন্যাস / নকশা

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

সবচেয়ে খারাপ পরিস্থিতি: ব্রোকেন রাউটিং

বিকল্পভাবে, একজন ব্যবহারকারী এমন একটি URL জুড়ে আসতে পারে যা আপনার সার্ভার দ্বারা পরিচালিত হয়, কিন্তু আপনার পরিষেবা কর্মী নয়। জম্বি লেআউট এবং শেষ প্রান্তে পূর্ণ একটি সাইট একটি নির্ভরযোগ্য PWA নয়।

সাফল্যের জন্য টিপস

কিন্তু আপনি একা নন! নিম্নলিখিত টিপস আপনাকে সেই অসুবিধাগুলি এড়াতে সাহায্য করতে পারে:

টেমপ্লেটিং এবং রাউটিং লাইব্রেরি ব্যবহার করুন যেখানে বহু-ভাষা বাস্তবায়ন রয়েছে

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

কিন্তু বেশ কিছু জনপ্রিয় টেমপ্লেটিং এবং রাউটিং ফ্রেমওয়ার্কের একাধিক ভাষায় বাস্তবায়ন রয়েছে। আপনি যদি জাভাস্ক্রিপ্টের সাথে সাথে আপনার বর্তমান সার্ভারের ভাষার সাথে কাজ করে এমন একটি খুঁজে পান, তাহলে আপনি আপনার পরিষেবা কর্মী এবং সার্ভারকে সিঙ্কে রাখার এক ধাপ কাছাকাছি।

নেস্টেড, টেমপ্লেটের পরিবর্তে অনুক্রমিক পছন্দ করুন

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

আপনার সার্ভিস ওয়ার্কারে স্ট্যাটিক এবং ডাইনামিক উভয় কন্টেন্ট ক্যাশে করুন

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

একেবারে প্রয়োজন হলেই নেটওয়ার্কে ব্লক করুন

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

সম্পদ