দীর্ঘ টাস্ক বিচ্ছিন্ন করতে scheduler.yield() ব্যবহার করুন

প্রকাশিত: মার্চ 6, 2025

Browser Support

  • ক্রোম: 129।
  • প্রান্ত: 129।
  • ফায়ারফক্স: সমর্থিত নয়।
  • সাফারি: সমর্থিত নয়।

Source

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

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

scheduler.yield একটি ergonomic API অফার করে যা ঠিক যা বলে তা করে: যে ফাংশনটিকে বলা হয় তার এক্সিকিউশন await scheduler.yield() এক্সপ্রেশনে বিরতি দেয় এবং মূল থ্রেডে ফল দেয়, টাস্কটি ভেঙে দেয়। বাকি ফাংশন-এর এক্সিকিউশন-যাকে ফাংশনের ধারাবাহিকতা বলা হয়-একটি নতুন ইভেন্ট-লুপ টাস্কে চালানোর জন্য নির্ধারিত হবে।

async function respondToUserClick() {
  giveImmediateFeedback();
  await scheduler.yield(); // Yield to the main thread.
  slowerComputation();
}

scheduler.yield এর সুনির্দিষ্ট সুবিধা হল যে পেজ দ্বারা সারিবদ্ধ অন্য কোনও অনুরূপ কাজ চালানোর আগে ফলনের পরে ধারাবাহিকতা চালানোর জন্য নির্ধারিত হয়। এটি নতুন কাজ শুরু করার চেয়ে একটি টাস্কের ধারাবাহিকতাকে অগ্রাধিকার দেয়।

setTimeout বা scheduler.postTask মতো ফাংশনগুলিও কাজগুলি ভাঙতে ব্যবহার করা যেতে পারে, তবে সেই ধারাবাহিকতাগুলি সাধারণত কোনও ইতিমধ্যে-সারিবদ্ধ নতুন কাজগুলির পরে চলে, সম্ভাব্যভাবে মূল থ্রেডে প্রাপ্ত হওয়া এবং তাদের কাজ সম্পূর্ণ করার মধ্যে দীর্ঘ বিলম্বের ঝুঁকি নিয়ে।

ফলন পরে অগ্রাধিকার ধারাবাহিকতা

scheduler.yield হল অগ্রাধিকারমূলক টাস্ক শিডিউলিং API এর অংশ। ওয়েব ডেভেলপার হিসাবে, আমরা সাধারণত যে ক্রমানুসারে ইভেন্ট লুপ সুস্পষ্ট অগ্রাধিকারের পরিপ্রেক্ষিতে কার্যগুলি চালায় সে সম্পর্কে কথা বলি না, তবে আপেক্ষিক অগ্রাধিকারগুলি সর্বদাই থাকে , যেমন যেকোন সারিবদ্ধ setTimeout কলব্যাকের পরে একটি requestIdleCallback কলব্যাক, বা একটি ট্রিগার করা ইনপুট ইভেন্ট লিসেনার সাধারণত একটি টাস্ক সেট আপ setTimeout(callback, 0) আগে চলমান থাকে।

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

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

এখানে একটি উদাহরণ: দুটি ফাংশন, setTimeout ব্যবহার করে বিভিন্ন কাজ চালানোর জন্য সারিবদ্ধ।

setTimeout(myJob);
setTimeout(someoneElsesJob);

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

DevTools-এ সেই কাজটি দেখতে কেমন হতে পারে তা এখানে:

Chrome DevTools পারফরম্যান্স প্যানেলে দেখানো দুটি কাজ। দুটিই দীর্ঘ কাজ হিসেবে নির্দেশিত হয়েছে, ফাংশন 'myJob' প্রথম টাস্কের সম্পূর্ণ সম্পাদনের দায়িত্ব নেয় এবং 'someoneElsesJob' দ্বিতীয় টাস্কের সম্পূর্ণতা গ্রহণ করে।

myJob একটি দীর্ঘ টাস্ক হিসাবে ফ্ল্যাগ করা হয়েছে, এটি চালানোর সময় ব্রাউজারটিকে অন্য কিছু করা থেকে ব্লক করে। অনুমান করে এটি একটি প্রথম পক্ষের স্ক্রিপ্ট থেকে এসেছে, আমরা এটিকে ভেঙে দিতে পারি:

function myJob() {
  // Run part 1.
  myJobPart1();
  // Yield with setTimeout() to break up long task, then run part2.
  setTimeout(myJobPart2, 0);
}

কারণ myJobPart2 myJob মধ্যে setTimeout সাথে চালানোর জন্য নির্ধারিত ছিল, কিন্তু সেই সময়সূচীটি চলে যাওয়ার পরে someoneElsesJob ইতিমধ্যেই নির্ধারিত হওয়ার পরে , এখানে এক্সিকিউশন কেমন হবে:

Chrome DevTools পারফরম্যান্স প্যানেলে দেখানো তিনটি কাজ। প্রথমটি 'myJobPart1' ফাংশন চালাচ্ছে, দ্বিতীয়টি 'someoneElsesJob' চালানোর একটি দীর্ঘ টাস্ক, এবং অবশেষে তৃতীয় কাজটি চলছে 'myJobPart2'।

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

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

scheduler.yield() লিখুন, যা অন্য যেকোন অনুরূপ কাজ শুরু করার চেয়ে সামান্য উচ্চ অগ্রাধিকার সারিতে আমন্ত্রণ জানানো যেকোন ফাংশনের ধারাবাহিকতা রাখে। যদি myJob এটি ব্যবহার করার জন্য পরিবর্তন করা হয়:

async function myJob() {
  // Run part 1.
  myJobPart1();
  // Yield with scheduler.yield() to break up long task, then run part2.
  await scheduler.yield();
  myJobPart2();
}

এখন মৃত্যুদন্ড এর মত দেখাচ্ছে:

Chrome DevTools পারফরম্যান্স প্যানেলে দেখানো দুটি কাজ। দুটিই দীর্ঘ কাজ হিসেবে নির্দেশিত হয়েছে, ফাংশন 'myJob' প্রথম টাস্কের সম্পূর্ণ সম্পাদনের দায়িত্ব নেয় এবং 'someoneElsesJob' দ্বিতীয় টাস্কের সম্পূর্ণতা গ্রহণ করে।

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

অগ্রাধিকার উত্তরাধিকার

বৃহত্তর অগ্রাধিকারযুক্ত টাস্ক শিডিউলিং API-এর অংশ হিসাবে, scheduler.yield() scheduler.postTask() এ উপলব্ধ সুস্পষ্ট অগ্রাধিকারের সাথে ভালভাবে রচনা করে। একটি অগ্রাধিকার স্পষ্টভাবে সেট না করে, একটি scheduler.yield() একটি scheduler.postTask() কলব্যাকের মধ্যে মূলত আগের উদাহরণের মতোই কাজ করবে।

যাইহোক, যদি একটি অগ্রাধিকার সেট করা হয়, যেমন একটি কম 'background' অগ্রাধিকার ব্যবহার করে:

async function lowPriorityJob() {
  part1();
  await scheduler.yield();
  part2();
}

scheduler.postTask(lowPriorityJob, {priority: 'background'});

ধারাবাহিকতা একটি অগ্রাধিকারের সাথে নির্ধারিত হবে যা অন্যান্য 'background' কাজগুলির চেয়ে বেশি - যেকোন মুলতুবি 'background' কাজের আগে প্রত্যাশিত অগ্রাধিকারযুক্ত ধারাবাহিকতা পাওয়া-কিন্তু এখনও অন্যান্য ডিফল্ট বা উচ্চ-অগ্রাধিকারমূলক কাজের তুলনায় কম অগ্রাধিকার; এটি 'background' কাজ থেকে যায়।

এর মানে হল যে আপনি যদি 'background' scheduler.postTask() (বা requestIdleCallback এর সাথে) কম অগ্রাধিকারের কাজ নির্ধারণ করেন, তাহলে একটি scheduler.yield() এর মধ্যে থাকা ধারাবাহিকতাও অপেক্ষা করবে যতক্ষণ না বেশিরভাগ অন্যান্য কাজ সম্পূর্ণ হয় এবং মূল থ্রেডটি চালানোর জন্য নিষ্ক্রিয় থাকে, যেটি আপনি কম-অগ্রাধিকারের কাজ থেকে পেতে চান।

কিভাবে API ব্যবহার করবেন

আপাতত, scheduler.yield() শুধুমাত্র Chromium-ভিত্তিক ব্রাউজারে উপলব্ধ, তাই এটি ব্যবহার করার জন্য আপনাকে বৈশিষ্ট্য সনাক্ত করতে হবে এবং অন্য ব্রাউজারগুলির জন্য ফলন করার একটি গৌণ উপায়ে ফিরে যেতে হবে।

scheduler-polyfill হল scheduler.postTask এবং scheduler.yield জন্য একটি ছোট পলিফিল যা অভ্যন্তরীণভাবে অন্যান্য ব্রাউজারে শিডিউলিং API-এর অনেক ক্ষমতা অনুকরণ করতে পদ্ধতির সংমিশ্রণ ব্যবহার করে (যদিও scheduler.yield() অগ্রাধিকার উত্তরাধিকার সমর্থিত নয়)।

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

wicg-task-scheduling প্রকারগুলিও ব্যবহার করা যেতে পারে টাইপ চেকিং এবং IDE সমর্থন পেতে যদি আপনি বৈশিষ্ট্য সনাক্ত করেন scheduler.yield() এবং নিজে একটি ফলব্যাক যোগ করেন।

আরও জানুন

API সম্পর্কে আরও তথ্যের জন্য এবং এটি কীভাবে কার্য অগ্রাধিকার এবং scheduler.postTask() এর সাথে ইন্টারঅ্যাক্ট করে, MDN-এ scheduler.yield() এবং অগ্রাধিকারযুক্ত টাস্ক শিডিউলিং ডক্স দেখুন।

দীর্ঘ কাজগুলি সম্পর্কে আরও জানতে, কীভাবে তারা ব্যবহারকারীর অভিজ্ঞতাকে প্রভাবিত করে এবং সেগুলি সম্পর্কে কী করতে হবে, দীর্ঘ কাজগুলি অপ্টিমাইজ করার বিষয়ে পড়ুন৷

,

প্রকাশিত: মার্চ 6, 2025

Browser Support

  • ক্রোম: 129।
  • প্রান্ত: 129।
  • ফায়ারফক্স: সমর্থিত নয়।
  • সাফারি: সমর্থিত নয়।

Source

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

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

scheduler.yield একটি ergonomic API অফার করে যা ঠিক যা বলে তা করে: যে ফাংশনটিকে বলা হয় তার এক্সিকিউশন await scheduler.yield() এক্সপ্রেশনে বিরতি দেয় এবং মূল থ্রেডে ফল দেয়, টাস্কটি ভেঙে দেয়। বাকি ফাংশন-এর এক্সিকিউশন-যাকে ফাংশনের ধারাবাহিকতা বলা হয়-একটি নতুন ইভেন্ট-লুপ টাস্কে চালানোর জন্য নির্ধারিত হবে।

async function respondToUserClick() {
  giveImmediateFeedback();
  await scheduler.yield(); // Yield to the main thread.
  slowerComputation();
}

scheduler.yield এর সুনির্দিষ্ট সুবিধা হল যে পেজ দ্বারা সারিবদ্ধ অন্য কোনও অনুরূপ কাজ চালানোর আগে ফলনের পরে ধারাবাহিকতা চালানোর জন্য নির্ধারিত হয়। এটি নতুন কাজ শুরু করার চেয়ে একটি টাস্কের ধারাবাহিকতাকে অগ্রাধিকার দেয়।

setTimeout বা scheduler.postTask মতো ফাংশনগুলিও কাজগুলি ভাঙতে ব্যবহার করা যেতে পারে, তবে সেই ধারাবাহিকতাগুলি সাধারণত কোনও ইতিমধ্যে-সারিবদ্ধ নতুন কাজগুলির পরে চলে, সম্ভাব্যভাবে মূল থ্রেডে প্রাপ্ত হওয়া এবং তাদের কাজ সম্পূর্ণ করার মধ্যে দীর্ঘ বিলম্বের ঝুঁকি নিয়ে।

ফলন পরে অগ্রাধিকার ধারাবাহিকতা

scheduler.yield হল অগ্রাধিকারমূলক টাস্ক শিডিউলিং API এর অংশ। ওয়েব ডেভেলপার হিসাবে, আমরা সাধারণত যে ক্রমানুসারে ইভেন্ট লুপ সুস্পষ্ট অগ্রাধিকারের পরিপ্রেক্ষিতে কার্যগুলি চালায় সে সম্পর্কে কথা বলি না, তবে আপেক্ষিক অগ্রাধিকারগুলি সর্বদাই থাকে , যেমন যেকোন সারিবদ্ধ setTimeout কলব্যাকের পরে একটি requestIdleCallback কলব্যাক, বা একটি ট্রিগার করা ইনপুট ইভেন্ট লিসেনার সাধারণত একটি টাস্ক সেট আপ setTimeout(callback, 0) আগে চলমান থাকে।

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

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

এখানে একটি উদাহরণ: দুটি ফাংশন, setTimeout ব্যবহার করে বিভিন্ন কাজ চালানোর জন্য সারিবদ্ধ।

setTimeout(myJob);
setTimeout(someoneElsesJob);

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

DevTools-এ সেই কাজটি দেখতে কেমন হতে পারে তা এখানে:

Chrome DevTools পারফরম্যান্স প্যানেলে দেখানো দুটি কাজ। দুটিই দীর্ঘ কাজ হিসেবে নির্দেশিত হয়েছে, ফাংশন 'myJob' প্রথম টাস্কের সম্পূর্ণ সম্পাদনের দায়িত্ব নেয় এবং 'someoneElsesJob' দ্বিতীয় টাস্কের সম্পূর্ণতা গ্রহণ করে।

myJob একটি দীর্ঘ টাস্ক হিসাবে ফ্ল্যাগ করা হয়েছে, এটি চালানোর সময় ব্রাউজারটিকে অন্য কিছু করা থেকে ব্লক করে। অনুমান করে এটি একটি প্রথম পক্ষের স্ক্রিপ্ট থেকে এসেছে, আমরা এটিকে ভেঙে দিতে পারি:

function myJob() {
  // Run part 1.
  myJobPart1();
  // Yield with setTimeout() to break up long task, then run part2.
  setTimeout(myJobPart2, 0);
}

কারণ myJobPart2 myJob মধ্যে setTimeout সাথে চালানোর জন্য নির্ধারিত ছিল, কিন্তু সেই সময়সূচীটি চলে যাওয়ার পরে someoneElsesJob ইতিমধ্যেই নির্ধারিত হওয়ার পরে , এখানে এক্সিকিউশন কেমন হবে:

Chrome DevTools পারফরম্যান্স প্যানেলে দেখানো তিনটি কাজ। প্রথমটি 'myJobPart1' ফাংশন চালাচ্ছে, দ্বিতীয়টি 'someoneElsesJob' চালানোর একটি দীর্ঘ টাস্ক, এবং অবশেষে তৃতীয় কাজটি চলছে 'myJobPart2'।

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

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

scheduler.yield() লিখুন, যা অন্য যেকোন অনুরূপ কাজ শুরু করার চেয়ে সামান্য উচ্চ অগ্রাধিকার সারিতে আমন্ত্রণ জানানো যেকোন ফাংশনের ধারাবাহিকতা রাখে। যদি myJob এটি ব্যবহার করার জন্য পরিবর্তন করা হয়:

async function myJob() {
  // Run part 1.
  myJobPart1();
  // Yield with scheduler.yield() to break up long task, then run part2.
  await scheduler.yield();
  myJobPart2();
}

এখন মৃত্যুদন্ড এর মত দেখাচ্ছে:

Chrome DevTools পারফরম্যান্স প্যানেলে দেখানো দুটি কাজ। দুটিই দীর্ঘ কাজ হিসেবে নির্দেশিত হয়েছে, ফাংশন 'myJob' প্রথম টাস্কের সম্পূর্ণ সম্পাদনের দায়িত্ব নেয় এবং 'someoneElsesJob' দ্বিতীয় টাস্কের সম্পূর্ণতা গ্রহণ করে।

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

অগ্রাধিকার উত্তরাধিকার

বৃহত্তর অগ্রাধিকারযুক্ত টাস্ক শিডিউলিং API-এর অংশ হিসাবে, scheduler.yield() scheduler.postTask() এ উপলব্ধ সুস্পষ্ট অগ্রাধিকারের সাথে ভালভাবে রচনা করে। একটি অগ্রাধিকার স্পষ্টভাবে সেট না করে, একটি scheduler.yield() একটি scheduler.postTask() কলব্যাকের মধ্যে মূলত আগের উদাহরণের মতোই কাজ করবে।

যাইহোক, যদি একটি অগ্রাধিকার সেট করা হয়, যেমন একটি কম 'background' অগ্রাধিকার ব্যবহার করে:

async function lowPriorityJob() {
  part1();
  await scheduler.yield();
  part2();
}

scheduler.postTask(lowPriorityJob, {priority: 'background'});

ধারাবাহিকতা একটি অগ্রাধিকারের সাথে নির্ধারিত হবে যা অন্যান্য 'background' কাজগুলির চেয়ে বেশি - যেকোন মুলতুবি 'background' কাজের আগে প্রত্যাশিত অগ্রাধিকারযুক্ত ধারাবাহিকতা পাওয়া-কিন্তু এখনও অন্যান্য ডিফল্ট বা উচ্চ-অগ্রাধিকারমূলক কাজের তুলনায় কম অগ্রাধিকার; এটি 'background' কাজ থেকে যায়।

এর মানে হল যে আপনি যদি 'background' scheduler.postTask() (বা requestIdleCallback এর সাথে) কম অগ্রাধিকারের কাজ নির্ধারণ করেন, তাহলে একটি scheduler.yield() এর মধ্যে থাকা ধারাবাহিকতাও অপেক্ষা করবে যতক্ষণ না বেশিরভাগ অন্যান্য কাজ সম্পূর্ণ হয় এবং মূল থ্রেডটি চালানোর জন্য নিষ্ক্রিয় থাকে, যেটি আপনি কম-অগ্রাধিকারের কাজ থেকে পেতে চান।

কিভাবে API ব্যবহার করবেন

আপাতত, scheduler.yield() শুধুমাত্র Chromium-ভিত্তিক ব্রাউজারে উপলব্ধ, তাই এটি ব্যবহার করার জন্য আপনাকে বৈশিষ্ট্য সনাক্ত করতে হবে এবং অন্য ব্রাউজারগুলির জন্য ফলন করার একটি গৌণ উপায়ে ফিরে যেতে হবে।

scheduler-polyfill হল scheduler.postTask এবং scheduler.yield জন্য একটি ছোট পলিফিল যা অভ্যন্তরীণভাবে অন্যান্য ব্রাউজারে শিডিউলিং API-এর অনেক ক্ষমতা অনুকরণ করতে পদ্ধতির সংমিশ্রণ ব্যবহার করে (যদিও scheduler.yield() অগ্রাধিকার উত্তরাধিকার সমর্থিত নয়)।

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

wicg-task-scheduling প্রকারগুলিও ব্যবহার করা যেতে পারে টাইপ চেকিং এবং IDE সমর্থন পেতে যদি আপনি বৈশিষ্ট্য সনাক্ত করেন scheduler.yield() এবং নিজে একটি ফলব্যাক যোগ করেন।

আরও জানুন

API সম্পর্কে আরও তথ্যের জন্য এবং এটি কীভাবে কার্য অগ্রাধিকার এবং scheduler.postTask() এর সাথে ইন্টারঅ্যাক্ট করে, MDN-এ scheduler.yield() এবং অগ্রাধিকারযুক্ত টাস্ক শিডিউলিং ডক্স দেখুন।

দীর্ঘ কাজগুলি সম্পর্কে আরও জানতে, কীভাবে তারা ব্যবহারকারীর অভিজ্ঞতাকে প্রভাবিত করে এবং সেগুলি সম্পর্কে কী করতে হবে, দীর্ঘ কাজগুলি অপ্টিমাইজ করার বিষয়ে পড়ুন৷

,

প্রকাশিত: মার্চ 6, 2025

Browser Support

  • ক্রোম: 129।
  • প্রান্ত: 129।
  • ফায়ারফক্স: সমর্থিত নয়।
  • সাফারি: সমর্থিত নয়।

Source

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

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

scheduler.yield একটি ergonomic API অফার করে যা ঠিক যা বলে তা করে: যে ফাংশনটিকে বলা হয় তার এক্সিকিউশন await scheduler.yield() এক্সপ্রেশনে বিরতি দেয় এবং মূল থ্রেডে ফল দেয়, টাস্কটি ভেঙে দেয়। বাকি ফাংশন-এর এক্সিকিউশন-যাকে ফাংশনের ধারাবাহিকতা বলা হয়-একটি নতুন ইভেন্ট-লুপ টাস্কে চালানোর জন্য নির্ধারিত হবে।

async function respondToUserClick() {
  giveImmediateFeedback();
  await scheduler.yield(); // Yield to the main thread.
  slowerComputation();
}

scheduler.yield এর সুনির্দিষ্ট সুবিধা হল যে পেজ দ্বারা সারিবদ্ধ অন্য কোনও অনুরূপ কাজ চালানোর আগে ফলনের পরে ধারাবাহিকতা চালানোর জন্য নির্ধারিত হয়। এটি নতুন কাজ শুরু করার চেয়ে একটি টাস্কের ধারাবাহিকতাকে অগ্রাধিকার দেয়।

setTimeout বা scheduler.postTask মতো ফাংশনগুলিও কাজগুলি ভাঙতে ব্যবহার করা যেতে পারে, তবে সেই ধারাবাহিকতাগুলি সাধারণত কোনও ইতিমধ্যে-সারিবদ্ধ নতুন কাজগুলির পরে চলে, সম্ভাব্যভাবে মূল থ্রেডে প্রাপ্ত হওয়া এবং তাদের কাজ সম্পূর্ণ করার মধ্যে দীর্ঘ বিলম্বের ঝুঁকি নিয়ে।

ফলন পরে অগ্রাধিকার ধারাবাহিকতা

scheduler.yield হল অগ্রাধিকারমূলক টাস্ক শিডিউলিং API এর অংশ। ওয়েব ডেভেলপার হিসাবে, আমরা সাধারণত যে ক্রমানুসারে ইভেন্ট লুপ সুস্পষ্ট অগ্রাধিকারের পরিপ্রেক্ষিতে কার্যগুলি চালায় সে সম্পর্কে কথা বলি না, তবে আপেক্ষিক অগ্রাধিকারগুলি সর্বদাই থাকে , যেমন যেকোন সারিবদ্ধ setTimeout কলব্যাকের পরে একটি requestIdleCallback কলব্যাক, বা একটি ট্রিগার করা ইনপুট ইভেন্ট লিসেনার সাধারণত একটি টাস্ক সেট আপ setTimeout(callback, 0) আগে চলমান থাকে।

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

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

এখানে একটি উদাহরণ: দুটি ফাংশন, setTimeout ব্যবহার করে বিভিন্ন কাজ চালানোর জন্য সারিবদ্ধ।

setTimeout(myJob);
setTimeout(someoneElsesJob);

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

DevTools-এ সেই কাজটি দেখতে কেমন হতে পারে তা এখানে:

Chrome DevTools পারফরম্যান্স প্যানেলে দেখানো দুটি কাজ। দুটিই দীর্ঘ কাজ হিসেবে নির্দেশিত হয়েছে, ফাংশন 'myJob' প্রথম টাস্কের সম্পূর্ণ সম্পাদনের দায়িত্ব নেয় এবং 'someoneElsesJob' দ্বিতীয় টাস্কের সম্পূর্ণতা গ্রহণ করে।

myJob একটি দীর্ঘ টাস্ক হিসাবে ফ্ল্যাগ করা হয়েছে, এটি চালানোর সময় ব্রাউজারটিকে অন্য কিছু করা থেকে ব্লক করে। অনুমান করে এটি একটি প্রথম পক্ষের স্ক্রিপ্ট থেকে এসেছে, আমরা এটিকে ভেঙে দিতে পারি:

function myJob() {
  // Run part 1.
  myJobPart1();
  // Yield with setTimeout() to break up long task, then run part2.
  setTimeout(myJobPart2, 0);
}

কারণ myJobPart2 myJob মধ্যে setTimeout সাথে চালানোর জন্য নির্ধারিত ছিল, কিন্তু সেই সময়সূচীটি চলে যাওয়ার পরে someoneElsesJob ইতিমধ্যেই নির্ধারিত হওয়ার পরে , এখানে এক্সিকিউশন কেমন হবে:

Chrome DevTools পারফরম্যান্স প্যানেলে দেখানো তিনটি কাজ। প্রথমটি 'myJobPart1' ফাংশন চালাচ্ছে, দ্বিতীয়টি 'someoneElsesJob' চালানোর একটি দীর্ঘ টাস্ক, এবং অবশেষে তৃতীয় কাজটি চলছে 'myJobPart2'।

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

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

scheduler.yield() লিখুন, যা অন্য যেকোন অনুরূপ কাজ শুরু করার চেয়ে সামান্য উচ্চ অগ্রাধিকার সারিতে আমন্ত্রণ জানানো যেকোন ফাংশনের ধারাবাহিকতা রাখে। যদি myJob এটি ব্যবহার করার জন্য পরিবর্তন করা হয়:

async function myJob() {
  // Run part 1.
  myJobPart1();
  // Yield with scheduler.yield() to break up long task, then run part2.
  await scheduler.yield();
  myJobPart2();
}

এখন মৃত্যুদন্ড এর মত দেখাচ্ছে:

Chrome DevTools পারফরম্যান্স প্যানেলে দেখানো দুটি কাজ। দুটিই দীর্ঘ কাজ হিসেবে নির্দেশিত হয়েছে, ফাংশন 'myJob' প্রথম টাস্কের সম্পূর্ণ সম্পাদনের দায়িত্ব নেয় এবং 'someoneElsesJob' দ্বিতীয় টাস্কের সম্পূর্ণতা গ্রহণ করে।

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

অগ্রাধিকার উত্তরাধিকার

বৃহত্তর অগ্রাধিকারযুক্ত টাস্ক শিডিউলিং API-এর অংশ হিসাবে, scheduler.yield() scheduler.postTask() এ উপলব্ধ সুস্পষ্ট অগ্রাধিকারের সাথে ভালভাবে রচনা করে। একটি অগ্রাধিকার স্পষ্টভাবে সেট না করে, একটি scheduler.yield() একটি scheduler.postTask() কলব্যাকের মধ্যে মূলত আগের উদাহরণের মতোই কাজ করবে।

যাইহোক, যদি একটি অগ্রাধিকার সেট করা হয়, যেমন একটি কম 'background' অগ্রাধিকার ব্যবহার করে:

async function lowPriorityJob() {
  part1();
  await scheduler.yield();
  part2();
}

scheduler.postTask(lowPriorityJob, {priority: 'background'});

ধারাবাহিকতা একটি অগ্রাধিকারের সাথে নির্ধারিত হবে যা অন্যান্য 'background' কাজগুলির চেয়ে বেশি - যেকোন মুলতুবি 'background' কাজের আগে প্রত্যাশিত অগ্রাধিকারযুক্ত ধারাবাহিকতা পাওয়া-কিন্তু এখনও অন্যান্য ডিফল্ট বা উচ্চ-অগ্রাধিকারমূলক কাজের তুলনায় কম অগ্রাধিকার; এটি 'background' কাজ থেকে যায়।

এর মানে হল যে আপনি যদি 'background' scheduler.postTask() (বা requestIdleCallback এর সাথে) কম অগ্রাধিকারের কাজ নির্ধারণ করেন, তাহলে একটি scheduler.yield() এর মধ্যে থাকা ধারাবাহিকতাও অপেক্ষা করবে যতক্ষণ না বেশিরভাগ অন্যান্য কাজ সম্পূর্ণ হয় এবং মূল থ্রেডটি চালানোর জন্য নিষ্ক্রিয় থাকে, যেটি আপনি কম-অগ্রাধিকারের কাজ থেকে পেতে চান।

কিভাবে API ব্যবহার করবেন

আপাতত, scheduler.yield() শুধুমাত্র Chromium-ভিত্তিক ব্রাউজারে উপলব্ধ, তাই এটি ব্যবহার করার জন্য আপনাকে বৈশিষ্ট্য সনাক্ত করতে হবে এবং অন্য ব্রাউজারগুলির জন্য ফলন করার একটি গৌণ উপায়ে ফিরে যেতে হবে।

scheduler-polyfill হল scheduler.postTask এবং scheduler.yield জন্য একটি ছোট পলিফিল যা অভ্যন্তরীণভাবে অন্যান্য ব্রাউজারে শিডিউলিং API-এর অনেক ক্ষমতা অনুকরণ করতে পদ্ধতির সংমিশ্রণ ব্যবহার করে (যদিও scheduler.yield() অগ্রাধিকার উত্তরাধিকার সমর্থিত নয়)।

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

wicg-task-scheduling প্রকারগুলিও ব্যবহার করা যেতে পারে টাইপ চেকিং এবং IDE সমর্থন পেতে যদি আপনি বৈশিষ্ট্য সনাক্ত করেন scheduler.yield() এবং নিজে একটি ফলব্যাক যোগ করেন।

আরও জানুন

API সম্পর্কে আরও তথ্যের জন্য এবং এটি কীভাবে কার্য অগ্রাধিকার এবং scheduler.postTask() এর সাথে ইন্টারঅ্যাক্ট করে, MDN-এ scheduler.yield() এবং অগ্রাধিকারযুক্ত টাস্ক শিডিউলিং ডক্স দেখুন।

দীর্ঘ কাজগুলি সম্পর্কে আরও জানতে, কীভাবে তারা ব্যবহারকারীর অভিজ্ঞতাকে প্রভাবিত করে এবং সেগুলি সম্পর্কে কী করতে হবে, দীর্ঘ কাজগুলি অপ্টিমাইজ করার বিষয়ে পড়ুন৷

,

প্রকাশিত: মার্চ 6, 2025

Browser Support

  • ক্রোম: 129।
  • প্রান্ত: 129।
  • ফায়ারফক্স: সমর্থিত নয়।
  • সাফারি: সমর্থিত নয়।

Source

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

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

scheduler.yield একটি ergonomic API অফার করে যা ঠিক যা বলে তা করে: যে ফাংশনটিকে বলা হয় তার এক্সিকিউশন await scheduler.yield() এক্সপ্রেশনে বিরতি দেয় এবং মূল থ্রেডে ফল দেয়, টাস্কটি ভেঙে দেয়। বাকি ফাংশন-এর এক্সিকিউশন-যাকে ফাংশনের ধারাবাহিকতা বলা হয়-একটি নতুন ইভেন্ট-লুপ টাস্কে চালানোর জন্য নির্ধারিত হবে।

async function respondToUserClick() {
  giveImmediateFeedback();
  await scheduler.yield(); // Yield to the main thread.
  slowerComputation();
}

scheduler.yield এর সুনির্দিষ্ট সুবিধা হল যে পেজ দ্বারা সারিবদ্ধ অন্য কোনও অনুরূপ কাজ চালানোর আগে ফলনের পরে ধারাবাহিকতা চালানোর জন্য নির্ধারিত হয়। এটি নতুন কাজ শুরু করার চেয়ে একটি টাস্কের ধারাবাহিকতাকে অগ্রাধিকার দেয়।

setTimeout বা scheduler.postTask মতো ফাংশনগুলিও কাজগুলি ভাঙতে ব্যবহার করা যেতে পারে, তবে সেই ধারাবাহিকতাগুলি সাধারণত কোনও ইতিমধ্যে-সারিবদ্ধ নতুন কাজগুলির পরে চলে, সম্ভাব্যভাবে মূল থ্রেডে প্রাপ্ত হওয়া এবং তাদের কাজ সম্পূর্ণ করার মধ্যে দীর্ঘ বিলম্বের ঝুঁকি নিয়ে।

ফলন পরে অগ্রাধিকার ধারাবাহিকতা

scheduler.yield হল অগ্রাধিকারমূলক টাস্ক শিডিউলিং API এর অংশ। ওয়েব ডেভেলপার হিসাবে, আমরা সাধারণত যে ক্রমানুসারে ইভেন্ট লুপ সুস্পষ্ট অগ্রাধিকারের পরিপ্রেক্ষিতে কার্যগুলি চালায় সে সম্পর্কে কথা বলি না, তবে আপেক্ষিক অগ্রাধিকারগুলি সর্বদাই থাকে , যেমন যেকোন সারিবদ্ধ setTimeout কলব্যাকের পরে একটি requestIdleCallback কলব্যাক, বা একটি ট্রিগার করা ইনপুট ইভেন্ট লিসেনার সাধারণত একটি টাস্ক সেট আপ setTimeout(callback, 0) আগে চলমান থাকে।

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

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

এখানে একটি উদাহরণ: দুটি ফাংশন, setTimeout ব্যবহার করে বিভিন্ন কাজ চালানোর জন্য সারিবদ্ধ।

setTimeout(myJob);
setTimeout(someoneElsesJob);

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

DevTools-এ সেই কাজটি দেখতে কেমন হতে পারে তা এখানে:

Chrome DevTools পারফরম্যান্স প্যানেলে দেখানো দুটি কাজ। দুটিই দীর্ঘ কাজ হিসেবে নির্দেশিত হয়েছে, ফাংশন 'myJob' প্রথম টাস্কের সম্পূর্ণ সম্পাদনের দায়িত্ব নেয় এবং 'someoneElsesJob' দ্বিতীয় টাস্কের সম্পূর্ণতা গ্রহণ করে।

myJob একটি দীর্ঘ টাস্ক হিসাবে ফ্ল্যাগ করা হয়েছে, এটি চালানোর সময় ব্রাউজারটিকে অন্য কিছু করা থেকে ব্লক করে। অনুমান করে এটি একটি প্রথম পক্ষের স্ক্রিপ্ট থেকে এসেছে, আমরা এটিকে ভেঙে দিতে পারি:

function myJob() {
  // Run part 1.
  myJobPart1();
  // Yield with setTimeout() to break up long task, then run part2.
  setTimeout(myJobPart2, 0);
}

কারণ myJobPart2 myJob মধ্যে setTimeout সাথে চালানোর জন্য নির্ধারিত ছিল, কিন্তু সেই সময়সূচীটি চলে যাওয়ার পরে someoneElsesJob ইতিমধ্যেই নির্ধারিত হওয়ার পরে , এখানে এক্সিকিউশন কেমন হবে:

Chrome DevTools পারফরম্যান্স প্যানেলে দেখানো তিনটি কাজ। প্রথমটি 'myJobPart1' ফাংশন চালাচ্ছে, দ্বিতীয়টি 'someoneElsesJob' চালানোর একটি দীর্ঘ টাস্ক, এবং অবশেষে তৃতীয় কাজটি চলছে 'myJobPart2'।

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

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

scheduler.yield() লিখুন, যা অন্য যেকোন অনুরূপ কাজ শুরু করার চেয়ে সামান্য উচ্চ অগ্রাধিকার সারিতে আমন্ত্রণ জানানো যেকোন ফাংশনের ধারাবাহিকতা রাখে। যদি myJob এটি ব্যবহার করার জন্য পরিবর্তন করা হয়:

async function myJob() {
  // Run part 1.
  myJobPart1();
  // Yield with scheduler.yield() to break up long task, then run part2.
  await scheduler.yield();
  myJobPart2();
}

এখন মৃত্যুদন্ড এর মত দেখাচ্ছে:

Chrome DevTools পারফরম্যান্স প্যানেলে দেখানো দুটি কাজ। দুটিই দীর্ঘ কাজ হিসেবে নির্দেশিত হয়েছে, ফাংশন 'myJob' প্রথম টাস্কের সম্পূর্ণ সম্পাদনের দায়িত্ব নেয় এবং 'someoneElsesJob' দ্বিতীয় টাস্কের সম্পূর্ণতা গ্রহণ করে।

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

অগ্রাধিকার উত্তরাধিকার

বৃহত্তর অগ্রাধিকারযুক্ত টাস্ক শিডিউলিং API-এর অংশ হিসাবে, scheduler.yield() scheduler.postTask() এ উপলব্ধ সুস্পষ্ট অগ্রাধিকারের সাথে ভালভাবে রচনা করে। একটি অগ্রাধিকার স্পষ্টভাবে সেট না করে, একটি scheduler.yield() একটি scheduler.postTask() কলব্যাকের মধ্যে মূলত আগের উদাহরণের মতোই কাজ করবে।

যাইহোক, যদি একটি অগ্রাধিকার সেট করা হয়, যেমন একটি কম 'background' অগ্রাধিকার ব্যবহার করে:

async function lowPriorityJob() {
  part1();
  await scheduler.yield();
  part2();
}

scheduler.postTask(lowPriorityJob, {priority: 'background'});

ধারাবাহিকতা একটি অগ্রাধিকারের সাথে নির্ধারিত হবে যা অন্যান্য 'background' কাজগুলির চেয়ে বেশি - যেকোন মুলতুবি 'background' কাজের আগে প্রত্যাশিত অগ্রাধিকারযুক্ত ধারাবাহিকতা পাওয়া-কিন্তু এখনও অন্যান্য ডিফল্ট বা উচ্চ-অগ্রাধিকারমূলক কাজের তুলনায় কম অগ্রাধিকার; এটি 'background' কাজ থেকে যায়।

এর মানে হল যে আপনি যদি 'background' scheduler.postTask() (বা requestIdleCallback এর সাথে) কম অগ্রাধিকারের কাজ নির্ধারণ করেন, তাহলে একটি scheduler.yield() এর মধ্যে থাকা ধারাবাহিকতাও অপেক্ষা করবে যতক্ষণ না বেশিরভাগ অন্যান্য কাজ সম্পূর্ণ হয় এবং মূল থ্রেডটি চালানোর জন্য নিষ্ক্রিয় থাকে, যেটি আপনি কম-অগ্রাধিকারের কাজ থেকে পেতে চান।

কিভাবে API ব্যবহার করবেন

আপাতত, scheduler.yield() শুধুমাত্র Chromium-ভিত্তিক ব্রাউজারে উপলব্ধ, তাই এটি ব্যবহার করার জন্য আপনাকে বৈশিষ্ট্য সনাক্ত করতে হবে এবং অন্য ব্রাউজারগুলির জন্য ফলন করার একটি গৌণ উপায়ে ফিরে যেতে হবে।

scheduler-polyfill হল scheduler.postTask এবং scheduler.yield জন্য একটি ছোট পলিফিল যা অভ্যন্তরীণভাবে অন্যান্য ব্রাউজারে শিডিউলিং API-এর অনেক ক্ষমতা অনুকরণ করতে পদ্ধতির সংমিশ্রণ ব্যবহার করে (যদিও scheduler.yield() অগ্রাধিকার উত্তরাধিকার সমর্থিত নয়)।

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

wicg-task-scheduling প্রকারগুলিও ব্যবহার করা যেতে পারে টাইপ চেকিং এবং IDE সমর্থন পেতে যদি আপনি বৈশিষ্ট্য সনাক্ত করেন scheduler.yield() এবং নিজে একটি ফলব্যাক যোগ করেন।

আরও জানুন

API সম্পর্কে আরও তথ্যের জন্য এবং এটি কীভাবে কার্য অগ্রাধিকার এবং scheduler.postTask() এর সাথে ইন্টারঅ্যাক্ট করে, MDN-এ scheduler.yield() এবং অগ্রাধিকারযুক্ত টাস্ক শিডিউলিং ডক্স দেখুন।

দীর্ঘ কাজগুলি সম্পর্কে আরও জানতে, কীভাবে তারা ব্যবহারকারীর অভিজ্ঞতাকে প্রভাবিত করে এবং সেগুলি সম্পর্কে কী করতে হবে, দীর্ঘ কাজগুলি অপ্টিমাইজ করার বিষয়ে পড়ুন৷