একটি PWA তৈরি করার সময় পরিষেবা কর্মীদের সম্পর্কে বুলেটিন দল কী শিখেছে৷
একটি বহিরাগত-মুখী PWA তৈরি করার সময় Google বুলেটিন টিম যে পাঠগুলি শিখেছিল সেগুলি সম্পর্কে ব্লগ পোস্টগুলির একটি সিরিজের মধ্যে এটিই প্রথম৷ এই পোস্টগুলিতে আমরা আমাদের মুখোমুখি হওয়া কিছু চ্যালেঞ্জ, সেগুলি কাটিয়ে ওঠার জন্য আমরা যে পদ্ধতিগুলি নিয়েছি এবং সমস্যাগুলি এড়ানোর জন্য সাধারণ পরামর্শগুলি ভাগ করব৷ এটি কোনোভাবেই PWA-এর সম্পূর্ণ ওভারভিউ নয়। উদ্দেশ্য আমাদের দলের অভিজ্ঞতা থেকে শেখার ভাগ করা.
এই প্রথম পোস্টের জন্য আমরা প্রথমে একটু পটভূমির তথ্য কভার করব এবং তারপরে আমরা পরিষেবা কর্মীদের সম্পর্কে যে সমস্ত জিনিস শিখেছি সেগুলিতে ডুব দেব।
পটভূমি
বুলেটিন 2017 সালের মাঝামাঝি থেকে 2019 সালের মাঝামাঝি পর্যন্ত সক্রিয় ছিল।
কেন আমরা একটি PWA তৈরি করতে বেছে নিয়েছি
আমরা ডেভেলপমেন্ট প্রক্রিয়ার মধ্যে ঢোকার আগে, আসুন পরীক্ষা করে দেখি কেন একটি PWA নির্মাণ এই প্রকল্পের জন্য একটি আকর্ষণীয় বিকল্প ছিল:
- দ্রুত পুনরাবৃত্তি করার ক্ষমতা । বিশেষ করে মূল্যবান যেহেতু বুলেটিন একাধিক বাজারে চালিত হবে।
- একক কোড বেস । আমাদের ব্যবহারকারীরা Android এবং iOS এর মধ্যে মোটামুটি সমানভাবে বিভক্ত ছিল। একটি PWA মানে আমরা একটি একক ওয়েব অ্যাপ তৈরি করতে পারি যা উভয় প্ল্যাটফর্মে কাজ করবে। এতে দলের গতিবেগ ও প্রভাব বেড়ে যায়।
- দ্রুত আপডেট করা হয়েছে এবং ব্যবহারকারীর আচরণ থেকে স্বাধীন । PWAs স্বয়ংক্রিয়ভাবে আপডেট করতে পারে যা বন্য অঞ্চলে পুরানো ক্লায়েন্টদের পরিমাণ হ্রাস করে। আমরা ক্লায়েন্টদের জন্য খুব অল্প পরিমাণ মাইগ্রেশন সময়ের সাথে ব্রেকিং ব্যাকএন্ড পরিবর্তনগুলি পুশ করতে সক্ষম হয়েছি।
- প্রথম এবং তৃতীয় পক্ষের অ্যাপের সাথে সহজেই একত্রিত। এই ধরনের ইন্টিগ্রেশন অ্যাপের জন্য একটি প্রয়োজনীয়তা ছিল। একটি পিডব্লিউএ এর সাথে এটি প্রায়শই বোঝায় একটি URL খোলা।
- একটি অ্যাপ ইনস্টল করার ঘর্ষণ অপসারণ.
আমাদের কাঠামো
বুলেটিন-এর জন্য, আমরা পলিমার ব্যবহার করেছি, কিন্তু যেকোনো আধুনিক, ভাল-সমর্থিত ফ্রেমওয়ার্ক কাজ করবে।
আমরা সেবা কর্মীদের সম্পর্কে কি শিখেছি
একজন পরিষেবা কর্মী ছাড়া আপনার PWA থাকতে পারে না। পরিষেবা কর্মীরা আপনাকে অনেক শক্তি দেয়, যেমন উন্নত ক্যাশিং কৌশল, অফলাইন ক্ষমতা, ব্যাকগ্রাউন্ড সিঙ্ক, ইত্যাদি। যদিও পরিষেবা কর্মীরা কিছু জটিলতা যোগ করেন, আমরা দেখতে পেয়েছি যে তাদের সুবিধাগুলি অতিরিক্ত জটিলতার চেয়ে বেশি।
আপনি যদি পারেন এটা জেনারেট
হাত দ্বারা একটি পরিষেবা কর্মী স্ক্রিপ্ট লেখা এড়িয়ে চলুন. পরিষেবা কর্মীদের হাতে লেখার জন্য ম্যানুয়ালি ক্যাশে করা সংস্থানগুলি পরিচালনা করা এবং লজিক পুনরায় লেখার প্রয়োজন যা বেশিরভাগ পরিষেবা কর্মীদের লাইব্রেরিতে সাধারণ, যেমন Workbox ৷
বলা হয়েছে যে, আমাদের অভ্যন্তরীণ প্রযুক্তিগত স্ট্যাকের কারণে আমরা আমাদের পরিষেবা কর্মী তৈরি এবং পরিচালনা করতে একটি লাইব্রেরি ব্যবহার করতে পারিনি। নীচের আমাদের শিক্ষাগুলি মাঝে মাঝে এটি প্রতিফলিত করবে। আরও পড়ার জন্য নন-জেনারেটেড পরিষেবা কর্মীদের জন্য Pitfalls- এ যান।
সমস্ত লাইব্রেরি পরিষেবা-কর্মী-সামঞ্জস্যপূর্ণ নয়
কিছু JS লাইব্রেরি অনুমান করে যেগুলি প্রত্যাশিতভাবে কাজ করে না যখন একজন পরিষেবা কর্মী দ্বারা চালিত হয়। উদাহরণস্বরূপ, অনুমান করা window
বা document
উপলব্ধ, অথবা পরিষেবা কর্মীদের জন্য উপলব্ধ নয় এমন API ব্যবহার করে ( XMLHttpRequest
, স্থানীয় স্টোরেজ, ইত্যাদি)। নিশ্চিত করুন যে আপনার আবেদনের জন্য আপনার প্রয়োজনীয় কোনো সমালোচনামূলক লাইব্রেরি পরিষেবা-কর্মীর সাথে সামঞ্জস্যপূর্ণ। এই বিশেষ PWA-এর জন্য, আমরা প্রমাণীকরণের জন্য gapi.js ব্যবহার করতে চেয়েছিলাম, কিন্তু অক্ষম ছিলাম কারণ এটি পরিষেবা কর্মীদের সমর্থন করে না। লাইব্রেরি লেখকদেরও জাভাস্ক্রিপ্ট প্রসঙ্গে অপ্রয়োজনীয় অনুমানগুলি হ্রাস বা অপসারণ করা উচিত যেখানে পরিষেবা কর্মীদের ব্যবহারের ক্ষেত্রে সমর্থন করা সম্ভব, যেমন পরিষেবা কর্মী-বেমানান API এড়ানো এবং গ্লোবাল স্টেট এড়ানো ।
আরম্ভ করার সময় IndexedDB অ্যাক্সেস করা এড়িয়ে চলুন
আপনার পরিষেবা কর্মী স্ক্রিপ্ট শুরু করার সময় IndexedDB পড়বেন না, অন্যথায় আপনি এই অবাঞ্ছিত পরিস্থিতিতে পড়তে পারেন:
- ব্যবহারকারীর IndexedDB (IDB) সংস্করণ N সহ ওয়েব অ্যাপ রয়েছে
- নতুন ওয়েব অ্যাপটি IDB সংস্করণ N+1 দিয়ে পুশ করা হয়েছে
- ব্যবহারকারী PWA পরিদর্শন করে, যা নতুন পরিষেবা কর্মীর ডাউনলোড ট্রিগার করে
- ইভেন্ট হ্যান্ডলার
install
করার আগে নতুন পরিষেবা কর্মী IDB থেকে পড়ে, N থেকে N+1 এ যাওয়ার জন্য একটি IDB আপগ্রেড চক্র ট্রিগার করে - যেহেতু ব্যবহারকারীর কাছে N সংস্করণের সাথে পুরানো ক্লায়েন্ট রয়েছে, পরিষেবা কর্মী আপগ্রেড প্রক্রিয়াটি হ্যাং হয়ে যায় কারণ সক্রিয় সংযোগগুলি এখনও ডাটাবেসের পুরানো সংস্করণে খোলা থাকে
- পরিষেবা কর্মী হ্যাং, এবং ইনস্টল করা হয় না
আমাদের ক্ষেত্রে, পরিষেবা কর্মী ইনস্টলে ক্যাশে অবৈধ হয়ে গেছে, তাই যদি পরিষেবা কর্মী কখনও ইনস্টল না করে, ব্যবহারকারীরা কখনই আপডেট করা অ্যাপটি পান না।
এটা স্থিতিস্থাপক করুন
যদিও পরিষেবা কর্মী স্ক্রিপ্টগুলি ব্যাকগ্রাউন্ডে চালিত হয়, তবে সেগুলি যে কোনও সময়ে বন্ধ করা যেতে পারে, এমনকি যখন I/O অপারেশনের মাঝখানে (নেটওয়ার্ক, IDB, ইত্যাদি)। যে কোনো দীর্ঘ-চলমান প্রক্রিয়া যেকোনো সময়ে পুনরায় শুরু করা উচিত।
একটি সিঙ্ক প্রক্রিয়ার ক্ষেত্রে যা সার্ভারে বড় ফাইল আপলোড করে এবং IDB-তে সংরক্ষিত হয়, বাধাপ্রাপ্ত আংশিক আপলোডগুলির জন্য আমাদের সমাধান হল আমাদের অভ্যন্তরীণ আপলোড লাইব্রেরির পুনঃসূচনাযোগ্য সিস্টেমের সুবিধা নেওয়া, আপলোড করার আগে IDB-তে পুনরায় শুরু করা আপলোড URL সংরক্ষণ করা এবং ব্যবহার করা। যে URLটি একটি আপলোড পুনরায় শুরু করতে যদি এটি প্রথমবার সম্পূর্ণ না করে। এছাড়াও কোনো দীর্ঘস্থায়ী I/O অপারেশনের আগে, প্রতিটি রেকর্ডের জন্য আমরা কোথায় ছিলাম তা নির্দেশ করার জন্য রাষ্ট্রটি IDB-তে সংরক্ষণ করা হয়েছিল।
বৈশ্বিক রাষ্ট্রের উপর নির্ভর করবেন না
যেহেতু পরিষেবা কর্মীরা একটি ভিন্ন প্রেক্ষাপটে বিদ্যমান, আপনি যে অনেক চিহ্নের অস্তিত্বের আশা করতে পারেন তা উপস্থিত নেই৷ আমাদের অনেক কোড একটি window
প্রেক্ষাপটে, সেইসাথে একটি পরিষেবা কর্মী প্রসঙ্গ (যেমন লগিং, পতাকা, সিঙ্কিং ইত্যাদি) উভয় ক্ষেত্রেই চলে। কোডটি যে পরিষেবাগুলি ব্যবহার করে, যেমন স্থানীয় সঞ্চয়স্থান বা কুকিজ সম্পর্কে রক্ষণাত্মক হতে হবে৷ আপনি গ্লোবাল অবজেক্টকে এমনভাবে উল্লেখ করতে globalThis
ব্যবহার করতে পারেন যা সমস্ত প্রসঙ্গে কাজ করবে। এছাড়াও গ্লোবাল ভেরিয়েবলে সংরক্ষিত ডেটা অল্প পরিমাণে ব্যবহার করুন, কারণ স্ক্রিপ্টটি কখন বন্ধ করা হবে এবং রাষ্ট্রকে উচ্ছেদ করা হবে তার কোনো গ্যারান্টি নেই।
স্থানীয় উন্নয়ন
পরিষেবা কর্মীদের একটি প্রধান উপাদান স্থানীয়ভাবে সম্পদ ক্যাশে করা হয়. যাইহোক, বিকাশের সময় এটি আপনি যা চান তার ঠিক বিপরীত , বিশেষ করে যখন আপডেটগুলি অলসভাবে করা হয়। আপনি এখনও সার্ভার কর্মী ইনস্টল করতে চান যাতে আপনি এটির সাথে সমস্যাগুলি ডিবাগ করতে পারেন বা পটভূমি সিঙ্ক বা বিজ্ঞপ্তিগুলির মতো অন্যান্য APIগুলির সাথে কাজ করতে পারেন৷ Chrome-এ আপনি নেটওয়ার্ক চেকবক্সের জন্য বাইপাস ( অ্যাপ্লিকেশন প্যানেল > পরিষেবা কর্মী ফলক) সক্ষম করে Chrome DevTools-এর মাধ্যমে এটি অর্জন করতে পারেন এবং মেমরি ক্যাশে অক্ষম করার জন্য নেটওয়ার্ক প্যানেলে ক্যাশে অক্ষম করুন চেকবক্স সক্ষম করে৷ আরও ব্রাউজার কভার করার জন্য, আমরা আমাদের পরিষেবা কর্মীতে ক্যাশিং অক্ষম করার জন্য একটি পতাকা অন্তর্ভুক্ত করে একটি ভিন্ন সমাধান বেছে নিয়েছি যা ডেভেলপার বিল্ডগুলিতে ডিফল্টরূপে সক্রিয় থাকে৷ এটি নিশ্চিত করে যে devs সর্বদা কোনো ক্যাশিং সমস্যা ছাড়াই তাদের সাম্প্রতিকতম পরিবর্তনগুলি পায়। Cache-Control: no-cache
শিরোনামটি অন্তর্ভুক্ত করা গুরুত্বপূর্ণ এবং সেইসাথে ব্রাউজারকে কোনো সম্পদ ক্যাশে করা থেকে বিরত রাখা ।
বাতিঘর
লাইটহাউস PWA-এর জন্য উপযোগী বেশ কিছু ডিবাগিং টুল সরবরাহ করে। এটি একটি সাইট স্ক্যান করে এবং পিডব্লিউএ, কর্মক্ষমতা, অ্যাক্সেসযোগ্যতা, এসইও এবং অন্যান্য সেরা অনুশীলনগুলি কভার করে প্রতিবেদন তৈরি করে। আপনি যদি PWA হওয়ার মানদণ্ডের একটি ভঙ্গ করেন তবে আপনাকে সতর্ক করার জন্য আমরা ক্রমাগত ইন্টিগ্রেশনে Lighthouse চালানোর পরামর্শ দিই। এটি আসলে একবার আমাদের সাথে ঘটেছিল, যেখানে পরিষেবা কর্মী ইনস্টল করছিল না এবং আমরা একটি উত্পাদন ধাক্কার আগে এটি বুঝতে পারিনি। আমাদের CI-এর অংশ হিসেবে লাইটহাউস থাকলে তা প্রতিরোধ হতো।
ক্রমাগত বিতরণ আলিঙ্গন
যেহেতু পরিষেবা কর্মীরা স্বয়ংক্রিয়ভাবে আপডেট করতে পারে, ব্যবহারকারীদের আপগ্রেড সীমিত করার ক্ষমতা নেই। এটি উল্লেখযোগ্যভাবে বন্য অঞ্চলে পুরানো ক্লায়েন্টের পরিমাণ হ্রাস করে। ব্যবহারকারী যখন আমাদের অ্যাপটি খুলবে, তখন পরিষেবা কর্মী পুরানো ক্লায়েন্টকে পরিবেশন করবে যখন এটি অলসভাবে নতুন ক্লায়েন্ট ডাউনলোড করবে। নতুন ক্লায়েন্ট ডাউনলোড হয়ে গেলে, এটি ব্যবহারকারীকে নতুন বৈশিষ্ট্যগুলি অ্যাক্সেস করতে পৃষ্ঠাটি রিফ্রেশ করতে অনুরোধ করবে। এমনকি ব্যবহারকারী এই অনুরোধ উপেক্ষা করলেও, পরের বার যখন তারা পৃষ্ঠাটি রিফ্রেশ করবে তখন তারা ক্লায়েন্টের নতুন সংস্করণ পাবে। ফলস্বরূপ, একজন ব্যবহারকারীর পক্ষে iOS/Android অ্যাপগুলির জন্য একইভাবে আপডেটগুলি প্রত্যাখ্যান করা বেশ কঠিন।
আমরা ক্লায়েন্টদের জন্য খুব অল্প পরিমাণ মাইগ্রেশন সময়ের সাথে ব্রেকিং ব্যাকএন্ড পরিবর্তনগুলি পুশ করতে সক্ষম হয়েছি। সাধারণত, আমরা ব্যবহারকারীদের নতুন ক্লায়েন্টদের কাছে আপডেট করার জন্য এক মাস সময় দিই। যেহেতু অ্যাপটি পুরানো অবস্থায় পরিবেশন করা হবে, ব্যবহারকারীরা দীর্ঘ সময়ের জন্য অ্যাপটি না খুললে বয়স্ক ক্লায়েন্টদের পক্ষে বন্যের মধ্যে থাকা সম্ভব ছিল। আইওএস-এ, পরিষেবা কর্মীদের কয়েক সপ্তাহ পরে উচ্ছেদ করা হয় যাতে এই ঘটনা না ঘটে। অ্যান্ড্রয়েডের জন্য, বাসি থাকা অবস্থায় পরিবেশন না করে বা কয়েক সপ্তাহ পরে ম্যানুয়ালি কন্টেন্টের মেয়াদ শেষ করে এই সমস্যাটি প্রশমিত করা যেতে পারে। বাস্তবে, আমরা কখনও বাসি ক্লায়েন্টদের কাছ থেকে সমস্যার সম্মুখীন হইনি। একটি প্রদত্ত দল এখানে কতটা কঠোর হতে চায় তা তাদের নির্দিষ্ট ব্যবহারের ক্ষেত্রে নির্ভর করে, কিন্তু PWAs iOS/Android অ্যাপের তুলনায় উল্লেখযোগ্যভাবে বেশি নমনীয়তা প্রদান করে।
একটি পরিষেবা কর্মীর মধ্যে কুকি মান পাওয়া
কখনও কখনও এটি একটি পরিষেবা কর্মী প্রসঙ্গে কুকি মান অ্যাক্সেস করা প্রয়োজন. আমাদের ক্ষেত্রে, প্রথম পক্ষের API অনুরোধগুলি প্রমাণীকরণের জন্য একটি টোকেন তৈরি করতে আমাদের কুকি মানগুলি অ্যাক্সেস করতে হবে। একটি পরিষেবা কর্মীর মধ্যে, document.cookies
এর মতো সিঙ্ক্রোনাস API পাওয়া যায় না। আপনি সর্বদা কুকি মানগুলির অনুরোধ করার জন্য পরিষেবা কর্মী থেকে সক্রিয় (উইন্ডোযুক্ত) ক্লায়েন্টদের কাছে একটি বার্তা পাঠাতে পারেন, যদিও পরিষেবা কর্মীর পক্ষে কোনও উইন্ডোযুক্ত ক্লায়েন্ট উপলব্ধ না থাকলে পটভূমিতে চালানো সম্ভব, যেমন একটি ব্যাকগ্রাউন্ড সিঙ্কের সময়৷ এটিকে ঘিরে কাজ করার জন্য, আমরা আমাদের ফ্রন্টএন্ড সার্ভারে একটি এন্ডপয়েন্ট তৈরি করেছি যা কেবল ক্লায়েন্টের কাছে কুকির মানকে প্রতিধ্বনিত করে। পরিষেবা কর্মী এই শেষ পয়েন্টে একটি নেটওয়ার্ক অনুরোধ করেছেন এবং কুকির মানগুলি পেতে প্রতিক্রিয়াটি পড়ুন৷
কুকি স্টোর API- এর প্রকাশের সাথে, এটি সমর্থন করে এমন ব্রাউজারগুলির জন্য এই সমাধানের আর প্রয়োজন হবে না, কারণ এটি ব্রাউজার কুকিগুলিতে অ্যাসিঙ্ক্রোনাস অ্যাক্সেস প্রদান করে এবং পরিষেবা কর্মী সরাসরি ব্যবহার করতে পারে৷
অ-উত্পাদিত পরিষেবা কর্মীদের জন্য ক্ষতি
কোনো স্ট্যাটিক ক্যাশে ফাইল পরিবর্তন হলে পরিষেবা কর্মী স্ক্রিপ্ট পরিবর্তন নিশ্চিত করুন
একটি সাধারণ PWA প্যাটার্ন হল একজন পরিষেবা কর্মী তার install
পর্বের সময় সমস্ত স্ট্যাটিক অ্যাপ্লিকেশন ফাইল ইনস্টল করতে, যা ক্লায়েন্টদের পরবর্তী সমস্ত ভিজিটের জন্য সরাসরি ক্যাশে স্টোরেজ API ক্যাশে আঘাত করতে সক্ষম করে। পরিষেবা কর্মীরা শুধুমাত্র তখনই ইনস্টল করা হয় যখন ব্রাউজার শনাক্ত করে যে পরিষেবা কর্মী স্ক্রিপ্ট কোনোভাবে পরিবর্তিত হয়েছে, তাই আমাদের নিশ্চিত করতে হবে যে পরিষেবা কর্মী স্ক্রিপ্ট ফাইলটি কোনোভাবে পরিবর্তিত হয়েছে যখন একটি ক্যাশে ফাইল পরিবর্তিত হয়েছে। আমরা আমাদের সার্ভিস ওয়ার্কার স্ক্রিপ্টের মধ্যে স্ট্যাটিক রিসোর্স ফাইলসেটের একটি হ্যাশ এম্বেড করে ম্যানুয়ালি এটি করেছি, তাই প্রতিটি রিলিজ একটি স্বতন্ত্র পরিষেবা কর্মী জাভাস্ক্রিপ্ট ফাইল তৈরি করে। ওয়ার্কবক্সের মতো পরিষেবা কর্মী লাইব্রেরিগুলি আপনার জন্য এই প্রক্রিয়াটিকে স্বয়ংক্রিয় করে।
অংশ পরিক্ষাকরণ
গ্লোবাল অবজেক্টে ইভেন্ট শ্রোতাদের যোগ করে পরিষেবা কর্মী APIগুলি কাজ করে। উদাহরণ স্বরূপ:
self.addEventListener('fetch', (evt) => evt.respondWith(fetch('/foo')));
এটি পরীক্ষা করার জন্য একটি বেদনাদায়ক হতে পারে কারণ আপনাকে ইভেন্ট ট্রিগার, ইভেন্ট অবজেক্টকে উপহাস করতে হবে, respondWith()
কলব্যাকের জন্য অপেক্ষা করতে হবে এবং অবশেষে ফলাফলের উপর জোর দেওয়ার আগে প্রতিশ্রুতির জন্য অপেক্ষা করতে হবে। এটি গঠন করার একটি সহজ উপায় হল সমস্ত বাস্তবায়ন অন্য ফাইলে অর্পণ করা, যা আরও সহজে পরীক্ষা করা হয়।
import fetchHandler from './fetch_handler.js';
self.addEventListener('fetch', (evt) => evt.respondWith(fetchHandler(evt)));
একটি পরিষেবা কর্মী স্ক্রিপ্টের ইউনিট পরীক্ষা করার অসুবিধার কারণে, আমরা মূল পরিষেবা কর্মী স্ক্রিপ্টটিকে যতটা সম্ভব খালি-হাড় হিসাবে রেখেছি, বেশিরভাগ বাস্তবায়নকে অন্যান্য মডিউলগুলিতে বিভক্ত করেছি। যেহেতু এই ফাইলগুলি শুধুমাত্র স্ট্যান্ডার্ড জেএস মডিউল ছিল, সেগুলি স্ট্যান্ডার্ড টেস্ট লাইব্রেরিগুলির সাথে আরও সহজে ইউনিট পরীক্ষা করা যেতে পারে।
পার্ট 2 এবং 3 এর জন্য সাথে থাকুন
এই সিরিজের পার্ট 2 এবং 3 এ আমরা মিডিয়া ম্যানেজমেন্ট এবং iOS-নির্দিষ্ট সমস্যা সম্পর্কে কথা বলব। আপনি যদি আমাদেরকে Google-এ একটি PWA নির্মাণের বিষয়ে আরও জিজ্ঞাসা করতে চান, তাহলে আমাদের সাথে কীভাবে যোগাযোগ করবেন তা জানতে আমাদের লেখক প্রোফাইল দেখুন: