ব্রাউজারের মূল থ্রেড থেকে জাভাস্ক্রিপ্ট রান করতে ওয়েব ওয়ার্কার ব্যবহার করুন

অফ-মেন-থ্রেড আর্কিটেকচার আপনার অ্যাপের নির্ভরযোগ্যতা এবং ব্যবহারকারীর অভিজ্ঞতা উল্লেখযোগ্যভাবে উন্নত করতে পারে।

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

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

আমরা যদি চাই যে অত্যাধুনিক ওয়েব অ্যাপগুলি Core Web Vitals-এর মতো পারফর্ম্যান্স নির্দেশিকাগুলি নির্ভরযোগ্যভাবে পূরণ করুক—যা মানুষের উপলব্ধি এবং মনোবিজ্ঞান সম্পর্কে অভিজ্ঞতামূলক ডেটার উপর ভিত্তি করে তৈরি—তাহলে আমাদের কোড অফ দ্য মেইন থ্রেড (OMT) কার্যকর করার উপায় প্রয়োজন।

ওয়েব ওয়ার্কার কেন?

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

Core Web Vitals-এর ক্ষেত্রে, মূল থ্রেড থেকে কাজ চালানো উপকারী হতে পারে। বিশেষ করে, মূল থ্রেড থেকে ওয়েব ওয়ার্কারদের কাছে কাজ অফলোড করলে মূল থ্রেডের জন্য কন্টেনশন কমে যেতে পারে, যা কোনও পৃষ্ঠার ইন্টারঅ্যাকশন টু নেক্সট পেইন্ট (INP) রেসপন্সিভনেস মেট্রিক উন্নত করতে পারে। প্রসেস করার জন্য মূল থ্রেডে কম কাজ থাকলে, এটি ব্যবহারকারীর ইন্টার‍্যাকশনে আরও দ্রুত উত্তর দিতে পারে।

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

ওয়েব ওয়ার্কারের সাথে থ্রেডিং করা

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

জাভাস্ক্রিপ্টে, আমরা ওয়েব ওয়ার্কার থেকে প্রায় একই ধরনের কার্যকারিতা পেতে পারি, যা ২০০৭ সাল থেকে রয়েছে এবং ২০১২ সাল থেকে সব প্রধান ব্রাউজারে কাজ করে। ওয়েব ওয়ার্কার মূল থ্রেডের সাথে সমান্তরালভাবে চলে, তবে OS থ্রেডিংয়ের মতো এরা ভেরিয়েবল শেয়ার করতে পারে না।

ওয়েব ওয়ার্কার তৈরি করতে, ওয়ার্কার কনস্ট্রাক্টরে একটি ফাইল পাস করুন, যা আলাদা থ্রেডে সেই ফাইলটি রান করা শুরু করে:

const worker = new Worker("./worker.js");

postMessage API ব্যবহার করে মেসেজ পাঠানোর মাধ্যমে ওয়েব ওয়ার্কারের সাথে যোগাযোগ করুন। postMessage কলে প্যারামিটার হিসেবে মেসেজ ভ্যালু পাস করুন এবং তারপর ওয়ার্কারে মেসেজ ইভেন্ট লিসেনার যোগ করুন:

main.js

const worker = new Worker('./worker.js');
worker.postMessage([40, 2]);

worker.js

addEventListener('message', event => {
  const [a, b] = event.data;

  // Do stuff with the message
  // ...
});

মূল থ্রেডে মেসেজ পাঠাতে, ওয়েব ওয়ার্কারে একই postMessage API ব্যবহার করুন এবং মূল থ্রেডে ইভেন্ট লিসেনার সেট-আপ করুন:

main.js

const worker = new Worker('./worker.js');

worker.postMessage([40, 2]);
worker.addEventListener('message', event => {
  console.log(event.data);
});

worker.js

addEventListener('message', event => {
  const [a, b] = event.data;

  // Do stuff with the message
  postMessage(a + b);
});

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

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

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

আপনি Comlink-কে কোনও ওয়েব ওয়ার্কারে ইমপোর্ট করে এবং মূল থ্রেডে দেখানোর জন্য ফাংশনের সেট নির্ধারণ করে সেট-আপ করেন। তারপর আপনি মূল থ্রেডে Comlink ইমপোর্ট করেন, ওয়ার্কারকে র‍্যাপ করেন এবং এক্সপোজড ফাংশনে অ্যাক্সেস পান:

worker.js

import {expose} from 'comlink';

const api = {
  someMethod() {
    // ...
  }
}

expose(api);

main.js

import {wrap} from 'comlink';

const worker = new Worker('./worker.js');
const api = wrap(worker);

মেন থ্রেডে api ভেরিয়েবল ওয়েব ওয়ার্কারের মতোই কাজ করে, তবে প্রতিটি ফাংশন ভ্যালুর পরিবর্তে ভ্যালুর জন্য প্রমিস রিটার্ন করে।

কোন কোড আপনার ওয়েব ওয়ার্কারে সরানো উচিত?

ওয়েব ওয়ার্কারের কাছে DOM এবং WebUSB, WebRTC বা Web Audio-এর মতো অনেক API-এর অ্যাক্সেস থাকে না, তাই আপনি ওয়ার্কারের মধ্যে আপনার অ্যাপের এমন অংশ রাখতে পারবেন না যা এই ধরনের অ্যাক্সেসের উপর নির্ভর করে। তবুও, ওয়ার্কারের কাছে পাঠানো কোডের প্রতিটি ছোট অংশ মূল থ্রেডে আরও বেশি হেডরুম তৈরি করে, যাতে সেখানে অবশ্যই থাকতে হবে এমন জিনিস রাখা যায়—যেমন ইউজার ইন্টারফেস আপডেট করা।

ওয়েব ডেভেলপারদের একটি সমস্যা হল, বেশিরভাগ ওয়েব অ্যাপ Vue বা React-এর মতো UI ফ্রেমওয়ার্কের উপর নির্ভর করে অ্যাপের সবকিছু সাজায়; সবকিছুই ফ্রেমওয়ার্কের কম্পোনেন্ট এবং তাই DOM-এর সাথে সহজাতভাবে যুক্ত। That would seem to make it difficult to migrate to an OMT architecture.

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

PROXX: একটি OMT কেস স্টাডি

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

টিম গেমের ভিজ্যুয়াল স্টেটকে তার লজিক থেকে আলাদা করার জন্য ওয়েব ওয়ার্কার ব্যবহার করার সিদ্ধান্ত নিয়েছে:

  • প্রধান থ্রেড অ্যানিমেশন ও ট্রানজিশন রেন্ডার করার বিষয়টি ম্যানেজ করে।
  • ওয়েব ওয়ার্কার গেমের লজিক ম্যানেজ করে, যা সম্পূর্ণ কম্পিউটেশনাল।

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

PROXX-এর নন-OMT ভার্সনে UI রেসপন্স টাইম।

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

PROXX-এর OMT ভার্সনে UI রেসপন্স টাইম।

এটি একটি সচেতন ট্রেডঅফ: আমরা সীমাবদ্ধ ডিভাইসের ব্যবহারকারীদের এমন একটি অভিজ্ঞতা দিই যা হাই-এন্ড ডিভাইসের ব্যবহারকারীদের শাস্তি না দিয়ে আরও ভাল অনুভূতি দেয়।

OMT আর্কিটেকচারের প্রভাব

PROXX-এর উদাহরণ থেকে যেমন দেখা যায়, OMT আপনার অ্যাপকে আরও বেশি সংখ্যক ডিভাইসে নির্ভরযোগ্যভাবে রান করায়, তবে এটি আপনার অ্যাপকে আরও দ্রুত করে তোলে না:

  • আপনি শুধু মূল থ্রেড থেকে কাজ সরিয়ে দিচ্ছেন, কাজ কমাচ্ছেন না।
  • ওয়েব ওয়ার্কার ও মূল থ্রেডের মধ্যে অতিরিক্ত কমিউনিকেশন ওভারহেডের কারণে কখনও কখনও প্রসেস সামান্য ধীরগতির হয়ে যেতে পারে।

ট্রেড-অফ বিবেচনা করুন

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

বিভিন্ন ডিভাইস জুড়ে পারফর্ম্যান্সের অনিশ্চয়তার কারণে, OMT আর্কিটেকচারের লক্ষ্য হল ঝুঁকি কমানো—অত্যন্ত পরিবর্তনশীল রানটাইম পরিস্থিতিতে আপনার অ্যাপকে আরও শক্তিশালী করে তোলা—প্যারালাইজেশনের পারফর্ম্যান্সের সুবিধা নয়। রেজিলিয়েন্স বৃদ্ধি ও UX-এ উন্নতি স্পিডের সামান্য ট্রেডঅফের চেয়ে অনেক বেশি মূল্যবান।

টুলিং সম্পর্কিত নোট

ওয়েব ওয়ার্কার এখনও মূলধারায় আসেনি, তাই বেশিরভাগ মডিউল টুল—যেমন webpack এবং Rollup—এগুলিকে সরাসরি সাপোর্ট করে না। (যদিও Parcel করে!) সৌভাগ্যবশত, ওয়েবপ্যাক এবং রোলআপের সাথে ওয়েব ওয়ার্কারদের কাজ করার জন্য প্লাগ-ইন আছে:

সংক্ষেপে বলা হচ্ছে

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

এছাড়াও, OMT-এর সেকেন্ডারি সুবিধা আছে:

  • এটি জাভাস্ক্রিপ্ট এক্সিকিউশন খরচকে একটি পৃথক থ্রেডে সরিয়ে দেয়।
  • এটি পার্সিং খরচ সরায়, যার অর্থ UI আরও দ্রুত বুট আপ হতে পারে। এটি First Contentful Paint বা Time to Interactive-এর সময় কমিয়ে দিতে পারে, যার ফলে আপনার Lighthouse স্কোর বেড়ে যেতে পারে।

ওয়েব ওয়ার্কারদের নিয়ে ভয় পাওয়ার কিছু নেই। Comlink-এর মতো টুলগুলি কর্মীদের কাজ সহজ করে দিচ্ছে এবং বিভিন্ন ধরনের ওয়েব অ্যাপ্লিকেশনের জন্য তাদের একটি কার্যকর বিকল্প হিসেবে গড়ে তুলছে।