ব্রাউজারের প্রধান থ্রেড থেকে জাভাস্ক্রিপ্ট চালানোর জন্য ওয়েব কর্মীদের ব্যবহার করুন

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

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

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

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

কেন ওয়েব কর্মী?

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

কোর ওয়েব ভাইটালগুলির ক্ষেত্রে, মূল থ্রেডের বাইরে কাজ চালানো উপকারী হতে পারে। বিশেষ করে, মূল থ্রেড থেকে ওয়েব কর্মীদের কাছে কাজ অফলোড করা মূল থ্রেডের জন্য বিতর্ক কমাতে পারে, যা একটি পৃষ্ঠার ইন্টারঅ্যাকশন টু নেক্সট পেইন্ট (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);
});

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

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

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

আপনি কমলিংক সেট আপ করেন একটি ওয়েব ওয়ার্কারে ইম্পোর্ট করে এবং মূল থ্রেডে এক্সপোজ করার জন্য ফাংশনের একটি সেট সংজ্ঞায়িত করে। তারপর আপনি মূল থ্রেডে কমলিংক ইম্পোর্ট করেন, কর্মীকে মোড়ানো এবং এক্সপোজড ফাংশনগুলিতে অ্যাক্সেস পান:

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 ভেরিয়েবলটি ওয়েব ওয়ার্কারের মতোই আচরণ করে, তবে প্রতিটি ফাংশন মানের পরিবর্তে একটি মানের জন্য একটি প্রতিশ্রুতি প্রদান করে।

একজন ওয়েব কর্মীর কাছে কোন কোডটি স্থানান্তর করা উচিত?

Web workers don't have access to the DOM and many APIs like WebUSB , WebRTC , or Web Audio , so you can't put pieces of your app that rely on such access in a worker. Still, every small piece of code moved to a worker buys more headroom on the main thread for stuff that has to be there—like updating the user interface.

ওয়েব ডেভেলপারদের জন্য একটি সমস্যা হল যে বেশিরভাগ ওয়েব অ্যাপ অ্যাপের সবকিছু সাজানোর জন্য Vue বা React এর মতো UI ফ্রেমওয়ার্কের উপর নির্ভর করে; সবকিছুই ফ্রেমওয়ার্কের একটি উপাদান এবং তাই সহজাতভাবে DOM এর সাথে আবদ্ধ। এর ফলে OMT আর্কিটেকচারে স্থানান্তর করা কঠিন বলে মনে হয়।

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

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

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

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

  • মূল থ্রেডটি অ্যানিমেশন এবং ট্রানজিশনের রেন্ডারিং পরিচালনা করে।
  • একজন ওয়েব কর্মী গেম লজিক পরিচালনা করেন, যা সম্পূর্ণরূপে গণনামূলক।

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

PROXX এর নন-OMT সংস্করণে UI প্রতিক্রিয়া সময়।

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

PROXX এর OMT সংস্করণে UI প্রতিক্রিয়া সময়।

এটি একটি সচেতন বিনিময়: আমরা উচ্চমানের ডিভাইস ব্যবহারকারীদের শাস্তি না দিয়ে সীমাবদ্ধ ডিভাইস ব্যবহারকারীদের এমন একটি অভিজ্ঞতা প্রদান করি যা আরও ভালো বোধ করে

একটি OMT স্থাপত্যের প্রভাব

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

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

বিনিময় বিবেচনা করুন

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

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

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

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

সারসংক্ষেপ

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

এছাড়াও, OMT-এর গৌণ সুবিধা রয়েছে:

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

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