আপনাকে বলা হয়েছে "মূল থ্রেড ব্লক করবেন না" এবং "আপনার দীর্ঘ কাজগুলোকে ছোট ছোট অংশে ভাগ করুন", কিন্তু এই কাজগুলো করার অর্থ কী?
প্রকাশিত: ৩০ সেপ্টেম্বর, ২০২২, সর্বশেষ হালনাগাদ: ১৯ ডিসেম্বর, ২০২৪
জাভাস্ক্রিপ্ট অ্যাপ দ্রুত রাখার সাধারণ পরামর্শগুলো মূলত নিম্নলিখিত বিষয়গুলোর মধ্যেই সীমাবদ্ধ থাকে:
- প্রধান থ্রেডকে ব্লক করবেন না।
- আপনার দীর্ঘ কাজগুলোকে ছোট ছোট অংশে ভাগ করুন।
এটি একটি চমৎকার পরামর্শ, কিন্তু এর জন্য কী ধরনের কাজ করতে হবে? কম জাভাস্ক্রিপ্ট ব্যবহার করা ভালো, কিন্তু তার মানে কি ইউজার ইন্টারফেস স্বয়ংক্রিয়ভাবে আরও বেশি রেসপন্সিভ হবে? হতেও পারে, আবার নাও হতে পারে।
জাভাস্ক্রিপ্টে টাস্ক অপটিমাইজ করার পদ্ধতি বুঝতে হলে, প্রথমে আপনাকে জানতে হবে টাস্ক কী এবং ব্রাউজার কীভাবে সেগুলো পরিচালনা করে।
কাজ বলতে কী বোঝায়?
টাস্ক হলো ব্রাউজারের করা যেকোনো স্বতন্ত্র কাজ। এই কাজের মধ্যে রয়েছে রেন্ডারিং, এইচটিএমএল (HTML) ও সিএসএস (CSS) পার্সিং, জাভাস্ক্রিপ্ট (JavaScript) চালানো এবং অন্যান্য ধরনের কাজ, যেগুলোর ওপর আপনার সরাসরি নিয়ন্ত্রণ নাও থাকতে পারে। এই সবকিছুর মধ্যে, আপনার লেখা জাভাস্ক্রিপ্টই সম্ভবত টাস্কের সবচেয়ে বড় উৎস।

click ইভেন্ট হ্যান্ডলার দ্বারা শুরু হওয়া একটি টাস্ক।জাভাস্ক্রিপ্ট সম্পর্কিত কাজগুলো কয়েকটি উপায়ে পারফরম্যান্সকে প্রভাবিত করে:
- ব্রাউজার চালু হওয়ার সময় যখন একটি জাভাস্ক্রিপ্ট ফাইল ডাউনলোড করে, তখন সেটি সেই জাভাস্ক্রিপ্ট ফাইলটি পার্স ও কম্পাইল করার জন্য কাজগুলোকে সারিবদ্ধ করে রাখে, যাতে পরে তা চালানো যায়।
- পেজের জীবনচক্রের অন্যান্য সময়ে, যখন জাভাস্ক্রিপ্ট বিভিন্ন কাজ করে, যেমন ইভেন্ট হ্যান্ডলারের মাধ্যমে ইন্টারঅ্যাকশনের প্রতিক্রিয়া জানানো, জাভাস্ক্রিপ্ট-চালিত অ্যানিমেশন এবং অ্যানালিটিক্স সংগ্রহের মতো ব্যাকগ্রাউন্ড কার্যকলাপ, তখন টাস্কগুলো কিউতে জমা হয়।
ওয়েব ওয়ার্কার এবং অনুরূপ এপিআইগুলো ছাড়া এই সবকিছু মেইন থ্রেডে সংঘটিত হয়।
মূল বিষয়বস্তু কী?
মেইন থ্রেড হলো সেই জায়গা যেখানে ব্রাউজারের বেশিরভাগ কাজ চলে এবং আপনার লেখা প্রায় সমস্ত জাভাস্ক্রিপ্ট কোড এক্সিকিউট হয়।
প্রধান থ্রেড একবারে কেবল একটি কাজই সম্পাদন করতে পারে। যে কোনো কাজ যা ৫০ মিলিসেকেন্ডের বেশি সময় নেয়, তাকে দীর্ঘ কাজ (long task) বলা হয়। যে কাজগুলো ৫০ মিলিসেকেন্ড অতিক্রম করে, সেগুলোর মোট সময় থেকে ৫০ মিলিসেকেন্ড বিয়োগ করার পরের সময়টুকুকে সেই কাজের ব্লকিং পিরিয়ড (blocking period) বলা হয়।
যেকোনো দৈর্ঘ্যের কোনো কাজ চলার সময় ব্রাউজার ইন্টারঅ্যাকশনকে বাধা দেয়, কিন্তু কাজগুলো খুব বেশি সময় ধরে না চললে ব্যবহারকারী তা বুঝতে পারেন না। তবে, যখন অনেকগুলো দীর্ঘ কাজ চলতে থাকে এবং ব্যবহারকারী কোনো পৃষ্ঠার সাথে ইন্টারঅ্যাক্ট করার চেষ্টা করেন, তখন ইউজার ইন্টারফেসটি প্রতিক্রিয়াহীন মনে হবে, এবং মূল থ্রেডটি খুব দীর্ঘ সময়ের জন্য ব্লক হয়ে থাকলে এটি ভেঙেও যেতে পারে।

প্রধান থ্রেড যাতে বেশিক্ষণ আটকে না থাকে, সেজন্য আপনি একটি দীর্ঘ কাজকে কয়েকটি ছোট ছোট কাজে ভাগ করে নিতে পারেন।

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

পূর্ববর্তী চিত্রের উপরের অংশে, ব্যবহারকারীর কোনো ইন্টারঅ্যাকশনের কারণে কিউতে থাকা একটি ইভেন্ট হ্যান্ডলারকে শুরু হওয়ার আগে একটি দীর্ঘ কাজের জন্য অপেক্ষা করতে হচ্ছিল, যা ইন্টারঅ্যাকশনটি সম্পন্ন হতে বিলম্ব ঘটায়। এই পরিস্থিতিতে, ব্যবহারকারী হয়তো ল্যাগ বা ধীরগতি লক্ষ্য করেছেন। নিচের অংশে, ইভেন্ট হ্যান্ডলারটি আরও দ্রুত চলতে শুরু করতে পারে এবং ইন্টারঅ্যাকশনটি তাৎক্ষণিক বলে মনে হতে পারে।
কাজগুলোকে ভাগ করা কেন গুরুত্বপূর্ণ, তা এখন যেহেতু আপনি জানেন, তাই জাভাস্ক্রিপ্টে কীভাবে তা করতে হয় তা শিখে নিতে পারেন।
কাজ ব্যবস্থাপনার কৌশল
সফটওয়্যার আর্কিটেকচারে একটি প্রচলিত পরামর্শ হলো আপনার কাজকে ছোট ছোট ফাংশনে ভাগ করে নেওয়া:
function saveSettings () {
validateForm();
showSpinner();
saveToDatabase();
updateUI();
sendAnalytics();
}
এই উদাহরণে, saveSettings() নামে একটি ফাংশন আছে যা একটি ফর্ম যাচাই করতে, একটি স্পিনার দেখাতে, অ্যাপ্লিকেশন ব্যাকএন্ডে ডেটা পাঠাতে, ইউজার ইন্টারফেস আপডেট করতে এবং অ্যানালিটিক্স পাঠাতে পাঁচটি ফাংশনকে কল করে।
ধারণাগতভাবে, saveSettings() বেশ সুগঠিত। যদি আপনার এই ফাংশনগুলোর কোনো একটি ডিবাগ করার প্রয়োজন হয়, তবে প্রতিটি ফাংশন কী কাজ করে তা বোঝার জন্য আপনি প্রজেক্ট ট্রি-টি ঘুরে দেখতে পারেন। কাজকে এভাবে ভাগ করে নিলে প্রজেক্ট পরিচালনা ও রক্ষণাবেক্ষণ করা সহজ হয়ে যায়।
তবে, এখানে একটি সম্ভাব্য সমস্যা হলো, জাভাস্ক্রিপ্ট এই ফাংশনগুলোর প্রত্যেকটিকে আলাদা টাস্ক হিসেবে চালায় না, কারণ এগুলো saveSettings() ফাংশনের ভেতরেই এক্সিকিউট হয়। এর মানে হলো, পাঁচটি ফাংশনই একটি টাস্ক হিসেবে রান করবে।

saveSettings() নামের একটিমাত্র ফাংশন পাঁচটি ফাংশনকে কল করে। এই কাজটি একটি দীর্ঘ ও একক টাস্কের অংশ হিসেবে সম্পন্ন হয়, এবং পাঁচটি ফাংশনের কাজ শেষ না হওয়া পর্যন্ত যেকোনো দৃশ্যমান প্রতিক্রিয়া বন্ধ থাকে।সবচেয়ে ভালো পরিস্থিতিতে, ওই ফাংশনগুলোর মধ্যে মাত্র একটিই টাস্কটির মোট দৈর্ঘ্যে ৫০ মিলিসেকেন্ড বা তার বেশি যোগ করতে পারে। সবচেয়ে খারাপ পরিস্থিতিতে, এই ধরনের একাধিক টাস্ক আরও অনেক বেশি সময় ধরে চলতে পারে—বিশেষ করে সীমিত রিসোর্সযুক্ত ডিভাইসগুলোতে।
এই ক্ষেত্রে, ব্যবহারকারীর ক্লিকের মাধ্যমে saveSettings() ট্রিগার হয়, এবং যেহেতু সম্পূর্ণ ফাংশনটির কাজ শেষ না হওয়া পর্যন্ত ব্রাউজার কোনো প্রতিক্রিয়া দেখাতে পারে না, তাই এই দীর্ঘ প্রক্রিয়ার ফলে ইউজার ইন্টারফেস (UI) ধীর ও প্রতিক্রিয়াহীন হয়ে পড়ে এবং এটিকে একটি দুর্বল ইন্টারঅ্যাকশন টু নেক্সট পেইন্ট (INP) হিসেবে গণ্য করা হবে।
ম্যানুয়ালি কোড এক্সিকিউশন স্থগিত করুন
কম অগ্রাধিকারের কাজগুলোর আগে গুরুত্বপূর্ণ ব্যবহারকারী-সম্পর্কিত কাজ এবং UI প্রতিক্রিয়াগুলো সম্পন্ন করা নিশ্চিত করতে, আপনি আপনার কাজকে সংক্ষিপ্ত সময়ের জন্য থামিয়ে দিয়ে ব্রাউজারকে আরও গুরুত্বপূর্ণ কাজ চালানোর সুযোগ করে দিতে পারেন এবং এর জন্য মেইন থ্রেডকে সুযোগ দিতে পারেন।
কাজগুলোকে ছোট ছোট অংশে ভাগ করার জন্য ডেভেলপাররা যে পদ্ধতিগুলো ব্যবহার করেন, তার মধ্যে একটি হলো setTimeout() । এই কৌশলে, আপনি setTimeout() ফাংশনে ফাংশনটি পাস করেন। এর ফলে কলব্যাকের এক্সিকিউশন একটি আলাদা টাস্কে স্থগিত হয়ে যায়, এমনকি আপনি টাইমআউট 0 নির্দিষ্ট করলেও।
function saveSettings () {
// Do critical work that is user-visible:
validateForm();
showSpinner();
updateUI();
// Defer work that isn't user-visible to a separate task:
setTimeout(() => {
saveToDatabase();
sendAnalytics();
}, 0);
}
এটিকে ইল্ডিং (yielding) বলা হয়, এবং এটি এমন একাধিক ফাংশনের ক্ষেত্রে সবচেয়ে ভালো কাজ করে যেগুলোকে ক্রমানুসারে চালানোর প্রয়োজন হয়।
তবে, আপনার কোড সবসময় এইভাবে সাজানো নাও থাকতে পারে। উদাহরণস্বরূপ, আপনার কাছে প্রচুর পরিমাণে ডেটা থাকতে পারে যা একটি লুপের মাধ্যমে প্রসেস করা প্রয়োজন, এবং অনেকগুলো পুনরাবৃত্তি থাকলে সেই কাজটি করতে অনেক বেশি সময় লাগতে পারে।
function processData () {
for (const item of largeDataArray) {
// Process the individual item here.
}
}
ডেভেলপারদের সুবিধার কথা বিবেচনা করলে, এখানে setTimeout() ব্যবহার করা সমস্যাজনক। এবং পরপর পাঁচবার setTimeout() ব্যবহারের পর, ব্রাউজার প্রতিটি অতিরিক্ত setTimeout() এর জন্য ন্যূনতম ৫ মিলিসেকেন্ডের বিলম্ব আরোপ করা শুরু করবে।
yielding-এর ক্ষেত্রে setTimeout আরও একটি অসুবিধা আছে: যখন আপনি setTimeout ব্যবহার করে পরবর্তী কোনো টাস্কে কোড চালানোর জন্য স্থগিত করে মেইন থ্রেডে yield করেন, তখন সেই টাস্কটি কিউ-এর শেষে যুক্ত হয়ে যায়। যদি অন্য কোনো টাস্ক অপেক্ষায় থাকে, তবে সেগুলো আপনার স্থগিত করা কোডের আগে চলবে।
একটি বিশেষায়িত ইয়েল্ডিং এপিআই: scheduler.yield()
scheduler.yield() হলো একটি এপিআই যা ব্রাউজারের প্রধান থ্রেডকে সুযোগ ছেড়ে দেওয়ার জন্য বিশেষভাবে ডিজাইন করা হয়েছে।
এটি কোনো ল্যাঙ্গুয়েজ-লেভেল সিনট্যাক্স বা বিশেষ গঠন নয়; scheduler.yield() হলো এমন একটি ফাংশন যা একটি Promise রিটার্ন করে, যা ভবিষ্যতের কোনো টাস্কে রিজলভ হবে। সেই Promise রিজলভ হওয়ার পরে চালানোর জন্য চেইন করা যেকোনো কোড (তা স্পষ্ট .then() চেইনের মাধ্যমেই হোক বা কোনো async ফাংশনে await করার মাধ্যমেই হোক) তখন সেই ভবিষ্যতের টাস্কটিতেই রান করবে।
কার্যত: একটি await scheduler.yield() যুক্ত করলে, ফাংশনটি সেই মুহূর্তে তার কার্য সম্পাদন থামিয়ে দেবে এবং মূল থ্রেডকে কার্যভার হস্তান্তর করবে। ফাংশনের বাকি অংশের কার্য সম্পাদন—যাকে ফাংশনের ধারাবাহিকতা (continuation ) বলা হয়—একটি নতুন ইভেন্ট-লুপ টাস্কে চালানোর জন্য নির্ধারিত হবে। যখন সেই টাস্কটি শুরু হবে, তখন অপেক্ষাকৃত প্রমিসটি সমাধান (resolve) হবে এবং ফাংশনটি যেখান থেকে থেমেছিল সেখান থেকেই তার কার্য সম্পাদন চালিয়ে যাবে।
async function saveSettings () {
// Do critical work that is user-visible:
validateForm();
showSpinner();
updateUI();
// Yield to the main thread:
await scheduler.yield()
// Work that isn't user-visible, continued in a separate task:
saveToDatabase();
sendAnalytics();
}

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

scheduler.yield() ব্যবহার করেন, তখন কন্টিনিউয়েশনটি অন্য কাজে যাওয়ার আগে আগের অসমাপ্ত কাজটি পুনরায় শুরু করে।ক্রস-ব্রাউজার সমর্থন
scheduler.yield() এখনও সব ব্রাউজারে সমর্থিত নয়, তাই একটি ফলব্যাক প্রয়োজন।
একটি সমাধান হলো আপনার বিল্ডে scheduler-polyfill যুক্ত করা, এবং তারপর scheduler.yield() সরাসরি ব্যবহার করা যাবে; পলিফিলটি অন্যান্য টাস্ক-শিডিউলিং ফাংশনে ফিরে যাওয়ার বিষয়টি সামলে নেবে, ফলে এটি বিভিন্ন ব্রাউজারে একইভাবে কাজ করবে।
বিকল্পভাবে, একটি কম জটিল সংস্করণ কয়েকটি লাইনে লেখা যেতে পারে, যেখানে scheduler.yield() উপলব্ধ না থাকলে ফলব্যাক হিসেবে শুধু একটি Promise-এর মধ্যে setTimeout ব্যবহার করা হয়।
function yieldToMain () {
if (globalThis.scheduler?.yield) {
return scheduler.yield();
}
// Fall back to yielding with setTimeout.
return new Promise(resolve => {
setTimeout(resolve, 0);
});
}
যেসব ব্রাউজারে scheduler.yield() সাপোর্ট নেই, সেগুলো অগ্রাধিকারপ্রাপ্ত ধারাবাহিকতা পাবে না ঠিকই, কিন্তু ব্রাউজারকে প্রতিক্রিয়াশীল রাখার জন্য তারা নিজেদের সুবিধা অনুযায়ী কাজ করবে।
অবশেষে, এমন পরিস্থিতিও আসতে পারে যেখানে আপনার কোডের কন্টিনিউয়েশন অগ্রাধিকার না পেলে, মেইন থ্রেডে ইয়েল্ড করা সম্ভব হয় না (উদাহরণস্বরূপ, একটি পরিচিত ব্যস্ত পেজ, যেখানে ইয়েল্ড করলে কাজটি সম্পন্ন হতে বেশ কিছুক্ষণ সময় লেগে যাওয়ার ঝুঁকি থাকে)। সেক্ষেত্রে, scheduler.yield() এক ধরনের প্রগ্রেসিভ এনহ্যান্সমেন্ট হিসেবে বিবেচনা করা যেতে পারে: যেসব ব্রাউজারে scheduler.yield() উপলব্ধ, সেখানে ইয়েল্ড করুন, অন্যথায় কন্টিনিউ করুন।
এটি ফিচার ডিটেক্টিং এবং ফলব্যাক করে একটিমাত্র মাইক্রোটাস্কের জন্য অপেক্ষা করার মাধ্যমে একটি সহজ এক-লাইনের কমান্ডে করা যেতে পারে:
// Yield to the main thread if scheduler.yield() is available.
await globalThis.scheduler?.yield?.();
scheduler.yield() ব্যবহার করে দীর্ঘ সময় ধরে চলা কাজকে ভেঙে দিন।
scheduler.yield() ব্যবহারের এই পদ্ধতিগুলোর যেকোনো একটির সুবিধা হলো, আপনি যেকোনো async ফাংশনে এটিকে await করতে পারেন।
উদাহরণস্বরূপ, যদি আপনার চালানোর জন্য একাধিক কাজ থাকে যা প্রায়শই একত্রিত হয়ে একটি দীর্ঘ কাজে পরিণত হয়, তবে আপনি কাজটি ভাগ করার জন্য 'yield' ব্যবহার করতে পারেন।
async function runJobs(jobQueue) {
for (const job of jobQueue) {
// Run the job:
job();
// Yield to the main thread:
await yieldToMain();
}
}
runJobs() এর ধারাবাহিকতাকে অগ্রাধিকার দেওয়া হবে, কিন্তু ব্যবহারকারীর ইনপুটের দৃশ্যমান প্রতিক্রিয়া হিসেবে কাজ চালানোর মতো উচ্চ-অগ্রাধিকারের কাজগুলোও চলতে পারবে, এবং এর জন্য কাজের সম্ভাব্য দীর্ঘ তালিকা শেষ হওয়ার জন্য অপেক্ষা করতে হবে না।
তবে, এটি ইয়েল্ডিং-এর একটি কার্যকর ব্যবহার নয়। scheduler.yield() দ্রুত এবং কার্যকর, কিন্তু এর কিছু ওভারহেড আছে। যদি jobQueue তে থাকা কিছু জব খুব ছোট হয়, তাহলে এই ওভারহেডের কারণে আসল কাজটি সম্পাদনের চেয়ে ইয়েল্ডিং এবং রিজিউমিং-এ বেশি সময় ব্যয় হতে পারে।
একটি উপায় হলো কাজগুলোকে ব্যাচ করা, এবং শেষ yield-এর পর যথেষ্ট সময় অতিবাহিত হলেই কেবল কাজগুলোর মাঝে yield করা। কাজগুলোকে দীর্ঘ হওয়া থেকে বিরত রাখার জন্য একটি সাধারণ ডেডলাইন হলো ৫০ মিলিসেকেন্ড, কিন্তু দ্রুত সাড়া দেওয়ার ক্ষমতা এবং কাজের সারিটি সম্পূর্ণ করতে লাগা সময়ের মধ্যে ভারসাম্য রেখে এটি পরিবর্তন করা যেতে পারে।
async function runJobs(jobQueue, deadline=50) {
let lastYield = performance.now();
for (const job of jobQueue) {
// Run the job:
job();
// If it's been longer than the deadline, yield to the main thread:
if (performance.now() - lastYield > deadline) {
await yieldToMain();
lastYield = performance.now();
}
}
}
এর ফলে কাজগুলো এমনভাবে ভাগ করা হয় যাতে সেগুলো চলতে খুব বেশি সময় না নেয়, কিন্তু রানারটি প্রায় প্রতি ৫০ মিলিসেকেন্ড পর পর মূল থ্রেডের কাছে তার কাজের সুযোগ ছেড়ে দেয়।

isInputPending() ব্যবহার করবেন না।
isInputPending() API-টি ব্যবহারকারী কোনো পৃষ্ঠার সাথে ইন্টারঅ্যাক্ট করার চেষ্টা করেছে কিনা তা পরীক্ষা করার একটি উপায় প্রদান করে এবং শুধুমাত্র কোনো ইনপুট পেন্ডিং থাকলেই ফাংশনটিকে রিটার্ন করে।
এর ফলে, কোনো ইনপুট বাকি না থাকলে জাভাস্ক্রিপ্ট কাজ চালিয়ে যেতে পারে, এবং টাস্ক কিউ-এর একেবারে শেষে গিয়ে জমা হয় না। এর ফলে পারফরম্যান্সে উল্লেখযোগ্য উন্নতি হতে পারে, যেমনটা ‘ইন্টেন্ট টু শিপ’ -এ বিস্তারিতভাবে বলা হয়েছে; বিশেষ করে সেইসব সাইটের ক্ষেত্রে যারা অন্যথায় মেইন থ্রেডে ফিরে যেত না।
তবে, ঐ এপিআইটি চালু হওয়ার পর থেকে, বিশেষ করে আইএনপি (INP) প্রবর্তনের ফলে, ইয়েল্ডিং (yielding) সম্পর্কে আমাদের ধারণা আরও উন্নত হয়েছে। আমরা এখন আর এই এপিআইটি ব্যবহার করার সুপারিশ করি না , এবং এর পরিবর্তে বিভিন্ন কারণে ইনপুট পেন্ডিং (pending) থাকুক বা না থাকুক, ইয়েল্ডিং করার সুপারিশ করি:
- কিছু পরিস্থিতিতে, ব্যবহারকারী ইন্টারঅ্যাক্ট করা সত্ত্বেও
isInputPending()ভুলবশতfalseরিটার্ন করতে পারে। - শুধু ইনপুটই একমাত্র ক্ষেত্র নয় যেখানে কাজগুলো নমনীয় হওয়া উচিত। একটি রেসপন্সিভ ওয়েব পেজ তৈরির জন্য অ্যানিমেশন এবং অন্যান্য নিয়মিত ইউজার ইন্টারফেস আপডেটও সমান গুরুত্বপূর্ণ হতে পারে।
- পরবর্তীতে আরও ব্যাপক ইল্ডিং এপিআই চালু করা হয়েছে যা ইল্ডিং সংক্রান্ত বিষয়গুলোর সমাধান করে, যেমন
scheduler.postTask()এবংscheduler.yield()।
উপসংহার
টাস্ক ম্যানেজ করা একটি কঠিন কাজ, কিন্তু এটি নিশ্চিত করে যে আপনার পেজ ব্যবহারকারীর ইন্টারঅ্যাকশনে আরও দ্রুত সাড়া দেয়। টাস্ক ম্যানেজ এবং অগ্রাধিকার দেওয়ার জন্য কোনো একটি নির্দিষ্ট পরামর্শ নেই, বরং বিভিন্ন কৌশল রয়েছে। আবারও বলছি, টাস্ক ম্যানেজ করার সময় এই প্রধান বিষয়গুলো আপনাকে বিবেচনা করতে হবে:
- গুরুত্বপূর্ণ ও ব্যবহারকারী-কেন্দ্রিক কাজের জন্য মূল থ্রেডকে সুযোগ দিন।
- সুবিধাজনকভাবে ইয়েল্ড করতে এবং অগ্রাধিকারপ্রাপ্ত কন্টিনিউয়েশনগুলো পেতে
scheduler.yield()(একটি ক্রস-ব্রাউজার ফলব্যাক সহ) ব্যবহার করুন। - সবশেষে, আপনার দায়িত্বগুলোতে যতটা সম্ভব কম কাজ করুন।
scheduler.yield() , এর সাথে সম্পর্কিত সুস্পষ্ট টাস্ক-শিডিউলিং scheduler.postTask() , এবং টাস্ক অগ্রাধিকারকরণ সম্পর্কে আরও জানতে, Prioritized Task Scheduling API ডক্স দেখুন।
এই সরঞ্জামগুলির এক বা একাধিকের সাহায্যে, আপনি আপনার অ্যাপ্লিকেশনের কাজগুলিকে এমনভাবে সাজাতে পারবেন যাতে ব্যবহারকারীর প্রয়োজনকে অগ্রাধিকার দেওয়া হয় এবং একই সাথে কম গুরুত্বপূর্ণ কাজও সম্পন্ন হয়। এর ফলে একটি উন্নততর ব্যবহারকারী অভিজ্ঞতা তৈরি হবে যা আরও বেশি রেসপন্সিভ এবং ব্যবহারে আরও আনন্দদায়ক হবে।
এই নির্দেশিকাটির প্রযুক্তিগত যাচাই-বাছাইয়ের জন্য ফিলিপ ওয়ালটনকে বিশেষ ধন্যবাদ।
থাম্বনেইল ছবিটি আনস্প্ল্যাশ থেকে সংগৃহীত, সৌজন্যে আমির আলি মিরহাশেমিয়ান ।