দীর্ঘ কাজ অপ্টিমাইজ করুন

আপনাকে বলা হয়েছে "প্রধান থ্রেড ব্লক করবেন না" এবং "আপনার দীর্ঘ কাজগুলি ভেঙে ফেলুন", কিন্তু এই জিনিসগুলি করার অর্থ কী?

জাভাস্ক্রিপ্ট অ্যাপ্লিকেশানগুলিকে দ্রুত রাখার জন্য সাধারণ উপদেশগুলি নিম্নোক্ত পরামর্শগুলিকে ফোটাতে থাকে:

  • "প্রধান থ্রেড ব্লক করবেন না।"
  • "আপনার দীর্ঘ কাজগুলি ভেঙে দিন।"

এটা মহান উপদেশ, কিন্তু এটা কি কাজ জড়িত? কম জাভাস্ক্রিপ্ট শিপিং ভাল, কিন্তু এটি কি স্বয়ংক্রিয়ভাবে আরও প্রতিক্রিয়াশীল ব্যবহারকারী ইন্টারফেসের সাথে সমান হয়? হতে পারে, কিন্তু হয়তো না।

জাভাস্ক্রিপ্টে কাজগুলি কীভাবে অপ্টিমাইজ করা যায় তা বোঝার জন্য, আপনাকে প্রথমে জানতে হবে কাজগুলি কী এবং ব্রাউজার কীভাবে সেগুলি পরিচালনা করে৷

একটি টাস্ক কি?

একটি টাস্ক হল ব্রাউজার যে কোন আলাদা কাজ করে। সেই কাজের মধ্যে রয়েছে রেন্ডারিং, HTML এবং CSS পার্স করা, JavaScript চালানো এবং অন্যান্য ধরনের কাজ যার উপর আপনার সরাসরি নিয়ন্ত্রণ নাও থাকতে পারে। এই সবের মধ্যে, আপনি যে জাভাস্ক্রিপ্ট লেখেন তা সম্ভবত কাজের সবচেয়ে বড় উৎস।

Chrome-এর DevTools-এর পারফরম্যান্স প্রোফাইলারে দেখানো একটি টাস্কের ভিজ্যুলাইজেশন। কাজটি একটি স্ট্যাকের শীর্ষে, একটি ক্লিক ইভেন্ট হ্যান্ডলার, একটি ফাংশন কল এবং এর নীচে আরও আইটেম রয়েছে৷ টাস্কটি ডানদিকের কিছু রেন্ডারিং কাজও অন্তর্ভুক্ত করে।
একটি click ইভেন্ট হ্যান্ডলার দ্বারা শুরু করা একটি টাস্ক, Chrome DevTools-এর পারফরম্যান্স প্রোফাইলারে দেখানো হয়েছে৷

জাভাস্ক্রিপ্টের সাথে যুক্ত কার্যগুলি কয়েকটি উপায়ে কার্যক্ষমতাকে প্রভাবিত করে:

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

এই সমস্ত স্টাফ- ওয়েব কর্মী এবং অনুরূপ APIগুলি বাদ দিয়ে-প্রধান থ্রেডে ঘটে।

মূল থ্রেড কি?

প্রধান থ্রেড হল যেখানে বেশিরভাগ কাজ ব্রাউজারে চলে এবং যেখানে আপনার লেখা প্রায় সমস্ত জাভাস্ক্রিপ্ট চালানো হয়।

প্রধান থ্রেড একটি সময়ে শুধুমাত্র একটি কাজ প্রক্রিয়া করতে পারে. 50 মিলিসেকেন্ডের বেশি সময় লাগে এমন যেকোনো কাজ একটি দীর্ঘ কাজ । 50 মিলিসেকেন্ডের বেশি কাজের জন্য, টাস্কের মোট সময় বিয়োগ 50 মিলিসেকেন্ড টাস্কের ব্লকিং সময়কাল হিসাবে পরিচিত।

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

Chrome এর DevTools এর পারফরম্যান্স প্রোফাইলারে একটি দীর্ঘ টাস্ক৷ টাস্কের ব্লকিং অংশ (50 মিলিসেকেন্ডের বেশি) লাল তির্যক স্ট্রাইপের প্যাটার্ন দিয়ে চিত্রিত করা হয়েছে।
ক্রোমের পারফরম্যান্স প্রোফাইলারে চিত্রিত একটি দীর্ঘ টাস্ক৷ লম্বা টাস্কগুলি টাস্কের কোণে একটি লাল ত্রিভুজ দ্বারা নির্দেশিত হয়, টাস্কের ব্লকিং অংশটি তির্যক লাল স্ট্রাইপের প্যাটার্নে ভরা থাকে।

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

একটি দীর্ঘ টাস্ক বনাম একই টাস্ক ছোট টাস্কে বিভক্ত। লম্বা টাস্ক হল একটি বড় আয়তক্ষেত্র, যেখানে খণ্ডিত টাস্ক হল পাঁচটি ছোট বাক্স যা সম্মিলিতভাবে লম্বা টাস্কের সমান প্রস্থ।
একটি একক দীর্ঘ টাস্ক বনাম সেই একই টাস্কের ভিজ্যুয়ালাইজেশন পাঁচটি ছোট টাস্কে বিভক্ত।

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

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

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

এখন যেহেতু আপনি জানেন যে কেন কাজগুলি বিচ্ছিন্ন করা গুরুত্বপূর্ণ, আপনি জাভাস্ক্রিপ্টে এটি কীভাবে করবেন তা শিখতে পারেন।

টাস্ক ম্যানেজমেন্ট কৌশল

সফ্টওয়্যার আর্কিটেকচারে একটি সাধারণ উপদেশ হল আপনার কাজকে ছোট ফাংশনে বিভক্ত করা:

function saveSettings () {
  validateForm();
  showSpinner();
  saveToDatabase();
  updateUI();
  sendAnalytics();
}

এই উদাহরণে, saveSettings() নামে একটি ফাংশন আছে যা একটি ফর্ম যাচাই করতে, একটি স্পিনার দেখাতে, অ্যাপ্লিকেশন ব্যাকএন্ডে ডেটা পাঠাতে, ব্যবহারকারীর ইন্টারফেস আপডেট করতে এবং বিশ্লেষণ পাঠাতে পাঁচটি ফাংশন কল করে।

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

এখানে একটি সম্ভাব্য সমস্যা, যদিও, জাভাস্ক্রিপ্ট এই প্রতিটি ফাংশনকে আলাদা কাজ হিসাবে চালায় না কারণ সেগুলি saveSettings() ফাংশনের মধ্যে কার্যকর করা হয়। এর মানে হল যে পাঁচটি ফাংশন একটি কাজ হিসাবে চলবে।

ক্রোমের পারফরম্যান্স প্রোফাইলারে দেখানো সেভ সেটিং ফাংশন। যদিও শীর্ষ-স্তরের ফাংশনটি অন্য পাঁচটি ফাংশনকে কল করে, সমস্ত কাজ একটি দীর্ঘ টাস্কে সঞ্চালিত হয় যা মূল থ্রেডকে ব্লক করে।
একটি একক ফাংশন saveSettings() যা পাঁচটি ফাংশনকে কল করে। কাজটি একটি দীর্ঘ একচেটিয়া কাজের অংশ হিসাবে চালানো হয়।

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

ম্যানুয়ালি কোড এক্সিকিউশন পিছিয়ে দিন

একটি পদ্ধতি ডেভেলপাররা কাজগুলিকে ছোট করে ভাগ করার জন্য ব্যবহার করেছেন 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() কাজের জন্য সঠিক টুল নয়-অন্তত এইভাবে ব্যবহার করার সময় নয়।

ফলন পয়েন্ট তৈরি করতে async / await ব্যবহার করুন

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

যেমনটি আগে ব্যাখ্যা করা হয়েছে, setTimeout প্রধান থ্রেডের জন্য ব্যবহার করা যেতে পারে। যদিও সুবিধার জন্য এবং ভাল পঠনযোগ্যতার জন্য, আপনি একটি Promise মধ্যে setTimeout কল করতে পারেন এবং কলব্যাক হিসাবে এর resolve পদ্ধতিটি পাস করতে পারেন।

function yieldToMain () {
  return new Promise(resolve => {
    setTimeout(resolve, 0);
  });
}

yieldToMain() ফাংশনের সুবিধা হল যে আপনি যেকোনো async ফাংশনে এটির জন্য await করতে পারেন। পূর্ববর্তী উদাহরণটি তৈরি করে, আপনি চালানোর জন্য ফাংশনগুলির একটি অ্যারে তৈরি করতে পারেন এবং প্রতিটি চালানোর পরে মূল থ্রেডে ফলন করতে পারেন:

async function saveSettings () {
  // Create an array of functions to run:
  const tasks = [
    validateForm,
    showSpinner,
    saveToDatabase,
    updateUI,
    sendAnalytics
  ]

  // Loop over the tasks:
  while (tasks.length > 0) {
    // Shift the first task off the tasks array:
    const task = tasks.shift();

    // Run the task:
    task();

    // Yield to the main thread:
    await yieldToMain();
  }
}

ফলাফল হল যে একসময়ের একচেটিয়া কাজ এখন আলাদা আলাদা কাজে বিভক্ত হয়ে গেছে।

একই সেভ সেটিংস ফাংশনটি ক্রোমের পারফরম্যান্স প্রোফাইলারে দেখানো হয়েছে, শুধুমাত্র ফলন সহ। ফলাফল হল একসময়ের একক কাজটি এখন পাঁচটি পৃথক টাস্কে বিভক্ত হয়েছে - প্রতিটি ফাংশনের জন্য একটি।
saveSettings() ফাংশন এখন তার চাইল্ড ফাংশনগুলিকে আলাদা টাস্ক হিসাবে চালায়।

একটি ডেডিকেটেড সময়সূচী API

setTimeout হল কার্যগুলি ভাঙার একটি কার্যকর উপায়, তবে এটির একটি ত্রুটি থাকতে পারে: আপনি যখন পরবর্তী টাস্কে চালানোর জন্য কোডটি বিলম্বিত করে মূল থ্রেডে যোগ দেন, তখন সেই টাস্কটি সারির শেষে যোগ করা হয়।

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

ব্রাউজার সমর্থন

  • ক্রোম: 94।
  • প্রান্ত: 94।
  • ফায়ারফক্স: একটি পতাকার পিছনে।
  • সাফারি: সমর্থিত নয়।

উৎস

শিডিউলার এপিআই postTask() ফাংশন অফার করে যা কাজের সূক্ষ্ম সময়সূচীর জন্য অনুমতি দেয় এবং ব্রাউজারকে কাজের অগ্রাধিকার দিতে সাহায্য করার একটি উপায় যাতে কম অগ্রাধিকারের কাজগুলি মূল থ্রেডে আসে। postTask() প্রতিশ্রুতি ব্যবহার করে, এবং তিনটি priority সেটিংসের একটি গ্রহণ করে:

  • সর্বনিম্ন অগ্রাধিকারমূলক কাজের জন্য 'background'
  • মাঝারি অগ্রাধিকারমূলক কাজের জন্য 'user-visible' । কোন priority সেট না থাকলে এটি ডিফল্ট।
  • 'user-blocking' গুরুত্বপূর্ণ কাজগুলির জন্য যা উচ্চ অগ্রাধিকারে চালানো প্রয়োজন।

একটি উদাহরণ হিসাবে নিম্নলিখিত কোডটি নিন, যেখানে postTask() API সর্বোচ্চ সম্ভাব্য অগ্রাধিকারে তিনটি কাজ চালানোর জন্য এবং বাকি দুটি কাজ সর্বনিম্ন সম্ভাব্য অগ্রাধিকারে চালানোর জন্য ব্যবহৃত হয়।

function saveSettings () {
  // Validate the form at high priority
  scheduler.postTask(validateForm, {priority: 'user-blocking'});

  // Show the spinner at high priority:
  scheduler.postTask(showSpinner, {priority: 'user-blocking'});

  // Update the database in the background:
  scheduler.postTask(saveToDatabase, {priority: 'background'});

  // Update the user interface at high priority:
  scheduler.postTask(updateUI, {priority: 'user-blocking'});

  // Send analytics data in the background:
  scheduler.postTask(sendAnalytics, {priority: 'background'});
};

এখানে, কাজগুলির অগ্রাধিকার এমনভাবে নির্ধারিত হয় যাতে ব্রাউজার-অগ্রাধিকারযুক্ত কাজগুলি-যেমন ব্যবহারকারীর মিথস্ক্রিয়া-প্রয়োজন অনুসারে তাদের মধ্যে কাজ করতে পারে।

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

postTask() কীভাবে ব্যবহার করা যেতে পারে তার এটি একটি সরল উদাহরণ। বিভিন্ন TaskController অবজেক্টগুলিকে ইনস্ট্যান্ট করা সম্ভব যা প্রয়োজন অনুসারে বিভিন্ন TaskController দৃষ্টান্তগুলির জন্য অগ্রাধিকার পরিবর্তন করার ক্ষমতা সহ কাজের মধ্যে অগ্রাধিকার ভাগ করতে পারে।

scheduler.yield() API ব্যবহার করে ধারাবাহিকতা সহ অন্তর্নির্মিত ফলন

ব্রাউজার সমর্থন

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

উৎস

scheduler.yield() একটি API বিশেষভাবে ব্রাউজারে প্রধান থ্রেড প্রদানের জন্য ডিজাইন করা হয়েছে। এর ব্যবহার yieldToMain() ফাংশনের সাথে সাদৃশ্যপূর্ণ যা এই নির্দেশিকাতে পূর্বে প্রদর্শিত হয়েছে:

async function saveSettings () {
  // Create an array of functions to run:
  const tasks = [
    validateForm,
    showSpinner,
    saveToDatabase,
    updateUI,
    sendAnalytics
  ]

  // Loop over the tasks:
  while (tasks.length > 0) {
    // Shift the first task off the tasks array:
    const task = tasks.shift();

    // Run the task:
    task();

    // Yield to the main thread with the scheduler
    // API's own yielding mechanism:
    await scheduler.yield();
  }
}

এই কোডটি মূলত পরিচিত, কিন্তু yieldToMain() ব্যবহার করার পরিবর্তে, এটি await scheduler.yield() ব্যবহার করে।

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

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

isInputPending() ব্যবহার করবেন না

ব্রাউজার সমর্থন

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

উৎস

isInputPending() API একজন ব্যবহারকারী একটি পৃষ্ঠার সাথে ইন্টারঅ্যাক্ট করার চেষ্টা করেছে কিনা তা পরীক্ষা করার একটি উপায় প্রদান করে এবং যদি একটি ইনপুট মুলতুবি থাকে তবেই ফল দেয়।

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

যাইহোক, সেই API চালু হওয়ার পর থেকে, ফলন সম্পর্কে আমাদের বোঝা বেড়েছে, বিশেষ করে INP প্রবর্তনের মাধ্যমে। আমরা আর এই API ব্যবহার করার পরামর্শ দিই না , এবং পরিবর্তে বিভিন্ন কারণে ইনপুট মুলতুবি থাকুক বা না থাকুক না কেন ফলন দেওয়ার সুপারিশ করি:

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

উপসংহার

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

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

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

ফিলিপ ওয়ালটনকে বিশেষ ধন্যবাদ তার এই নির্দেশিকাটির প্রযুক্তিগত পরীক্ষা করার জন্য।

থাম্বনেইল ছবি আনস্প্ল্যাশ থেকে নেওয়া, আমিরালি মিরহাশেমিয়ানের সৌজন্যে।

,

আপনাকে বলা হয়েছে "প্রধান থ্রেড ব্লক করবেন না" এবং "আপনার দীর্ঘ কাজগুলি ভেঙে ফেলুন", কিন্তু এই জিনিসগুলি করার অর্থ কী?

জাভাস্ক্রিপ্ট অ্যাপ্লিকেশানগুলিকে দ্রুত রাখার জন্য সাধারণ উপদেশগুলি নিম্নোক্ত পরামর্শগুলিকে ফোটাতে থাকে:

  • "প্রধান থ্রেড ব্লক করবেন না।"
  • "আপনার দীর্ঘ কাজগুলি ভেঙে দিন।"

এটা মহান উপদেশ, কিন্তু এটা কি কাজ জড়িত? কম জাভাস্ক্রিপ্ট শিপিং ভাল, কিন্তু এটি কি স্বয়ংক্রিয়ভাবে আরও প্রতিক্রিয়াশীল ব্যবহারকারী ইন্টারফেসের সাথে সমান হয়? হতে পারে, কিন্তু হয়তো না।

জাভাস্ক্রিপ্টে কাজগুলি কীভাবে অপ্টিমাইজ করা যায় তা বোঝার জন্য, আপনাকে প্রথমে জানতে হবে কাজগুলি কী এবং ব্রাউজার কীভাবে সেগুলি পরিচালনা করে৷

একটি টাস্ক কি?

একটি টাস্ক হল ব্রাউজার যে কোন আলাদা কাজ করে। সেই কাজের মধ্যে রয়েছে রেন্ডারিং, HTML এবং CSS পার্স করা, JavaScript চালানো এবং অন্যান্য ধরনের কাজ যার উপর আপনার সরাসরি নিয়ন্ত্রণ নাও থাকতে পারে। এই সবের মধ্যে, আপনি যে জাভাস্ক্রিপ্ট লেখেন তা সম্ভবত কাজের সবচেয়ে বড় উৎস।

Chrome-এর DevTools-এর পারফরম্যান্স প্রোফাইলারে দেখানো একটি টাস্কের ভিজ্যুলাইজেশন। কাজটি একটি স্ট্যাকের শীর্ষে, একটি ক্লিক ইভেন্ট হ্যান্ডলার, একটি ফাংশন কল এবং এর নীচে আরও আইটেম রয়েছে৷ টাস্কটি ডানদিকের কিছু রেন্ডারিং কাজও অন্তর্ভুক্ত করে।
একটি click ইভেন্ট হ্যান্ডলার দ্বারা শুরু করা একটি টাস্ক, Chrome DevTools-এর পারফরম্যান্স প্রোফাইলারে দেখানো হয়েছে৷

জাভাস্ক্রিপ্টের সাথে যুক্ত কার্যগুলি কয়েকটি উপায়ে কার্যক্ষমতাকে প্রভাবিত করে:

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

এই সমস্ত স্টাফ- ওয়েব কর্মী এবং অনুরূপ APIগুলি বাদ দিয়ে-প্রধান থ্রেডে ঘটে।

মূল থ্রেড কি?

প্রধান থ্রেড হল যেখানে বেশিরভাগ কাজ ব্রাউজারে চলে এবং যেখানে আপনার লেখা প্রায় সমস্ত জাভাস্ক্রিপ্ট চালানো হয়।

প্রধান থ্রেড একটি সময়ে শুধুমাত্র একটি কাজ প্রক্রিয়া করতে পারে. 50 মিলিসেকেন্ডের বেশি সময় লাগে এমন যেকোনো কাজ একটি দীর্ঘ কাজ । 50 মিলিসেকেন্ডের বেশি কাজের জন্য, টাস্কের মোট সময় বিয়োগ 50 মিলিসেকেন্ড টাস্কের ব্লকিং সময়কাল হিসাবে পরিচিত।

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

Chrome এর DevTools এর পারফরম্যান্স প্রোফাইলারে একটি দীর্ঘ টাস্ক৷ টাস্কের ব্লকিং অংশ (50 মিলিসেকেন্ডের বেশি) লাল তির্যক স্ট্রাইপের প্যাটার্ন দিয়ে চিত্রিত করা হয়েছে।
ক্রোমের পারফরম্যান্স প্রোফাইলারে চিত্রিত একটি দীর্ঘ টাস্ক৷ লম্বা টাস্কগুলি টাস্কের কোণে একটি লাল ত্রিভুজ দ্বারা নির্দেশিত হয়, টাস্কের ব্লকিং অংশটি তির্যক লাল স্ট্রাইপের প্যাটার্নে ভরা থাকে।

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

একটি দীর্ঘ টাস্ক বনাম একই টাস্ক ছোট টাস্কে বিভক্ত। লম্বা টাস্ক হল একটি বড় আয়তক্ষেত্র, যেখানে খণ্ডিত টাস্ক হল পাঁচটি ছোট বাক্স যা সম্মিলিতভাবে লম্বা টাস্কের সমান প্রস্থ।
একটি একক দীর্ঘ টাস্ক বনাম সেই একই টাস্কের ভিজ্যুয়ালাইজেশন পাঁচটি ছোট টাস্কে বিভক্ত।

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

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

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

এখন যেহেতু আপনি জানেন যে কেন কাজগুলি বিচ্ছিন্ন করা গুরুত্বপূর্ণ, আপনি জাভাস্ক্রিপ্টে এটি কীভাবে করবেন তা শিখতে পারেন।

টাস্ক ম্যানেজমেন্ট কৌশল

সফ্টওয়্যার আর্কিটেকচারে একটি সাধারণ উপদেশ হল আপনার কাজকে ছোট ফাংশনে বিভক্ত করা:

function saveSettings () {
  validateForm();
  showSpinner();
  saveToDatabase();
  updateUI();
  sendAnalytics();
}

এই উদাহরণে, saveSettings() নামে একটি ফাংশন আছে যা একটি ফর্ম যাচাই করতে, একটি স্পিনার দেখাতে, অ্যাপ্লিকেশন ব্যাকএন্ডে ডেটা পাঠাতে, ব্যবহারকারীর ইন্টারফেস আপডেট করতে এবং বিশ্লেষণ পাঠাতে পাঁচটি ফাংশন কল করে।

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

এখানে একটি সম্ভাব্য সমস্যা, যদিও, জাভাস্ক্রিপ্ট এই প্রতিটি ফাংশনকে আলাদা কাজ হিসাবে চালায় না কারণ সেগুলি saveSettings() ফাংশনের মধ্যে কার্যকর করা হয়। এর মানে হল যে পাঁচটি ফাংশন একটি কাজ হিসাবে চলবে।

ক্রোমের পারফরম্যান্স প্রোফাইলারে দেখানো সেভ সেটিং ফাংশন। যদিও শীর্ষ-স্তরের ফাংশনটি অন্য পাঁচটি ফাংশনকে কল করে, সমস্ত কাজ একটি দীর্ঘ টাস্কে সঞ্চালিত হয় যা মূল থ্রেডকে ব্লক করে।
একটি একক ফাংশন saveSettings() যা পাঁচটি ফাংশনকে কল করে। কাজটি একটি দীর্ঘ একচেটিয়া কাজের অংশ হিসাবে চালানো হয়।

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

ম্যানুয়ালি কোড এক্সিকিউশন পিছিয়ে দিন

একটি পদ্ধতি ডেভেলপাররা কাজগুলিকে ছোট করে ভাগ করার জন্য ব্যবহার করেছেন 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() কাজের জন্য সঠিক টুল নয়-অন্তত এইভাবে ব্যবহার করার সময় নয়।

ফলন পয়েন্ট তৈরি করতে async / await ব্যবহার করুন

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

যেমনটি আগে ব্যাখ্যা করা হয়েছে, setTimeout প্রধান থ্রেডের জন্য ব্যবহার করা যেতে পারে। যদিও সুবিধার জন্য এবং ভাল পঠনযোগ্যতার জন্য, আপনি একটি Promise মধ্যে setTimeout কল করতে পারেন এবং কলব্যাক হিসাবে এর resolve পদ্ধতিটি পাস করতে পারেন।

function yieldToMain () {
  return new Promise(resolve => {
    setTimeout(resolve, 0);
  });
}

yieldToMain() ফাংশনের সুবিধা হল যে আপনি যেকোনো async ফাংশনে এটির জন্য await করতে পারেন। পূর্ববর্তী উদাহরণটি তৈরি করে, আপনি চালানোর জন্য ফাংশনগুলির একটি অ্যারে তৈরি করতে পারেন এবং প্রতিটি চালানোর পরে মূল থ্রেডে ফলন করতে পারেন:

async function saveSettings () {
  // Create an array of functions to run:
  const tasks = [
    validateForm,
    showSpinner,
    saveToDatabase,
    updateUI,
    sendAnalytics
  ]

  // Loop over the tasks:
  while (tasks.length > 0) {
    // Shift the first task off the tasks array:
    const task = tasks.shift();

    // Run the task:
    task();

    // Yield to the main thread:
    await yieldToMain();
  }
}

ফলাফল হল যে একসময়ের একচেটিয়া কাজ এখন আলাদা আলাদা কাজে বিভক্ত হয়ে গেছে।

একই সেভ সেটিংস ফাংশনটি ক্রোমের পারফরম্যান্স প্রোফাইলারে দেখানো হয়েছে, শুধুমাত্র ফলন সহ। ফলাফল হল একসময়ের একক কাজটি এখন পাঁচটি পৃথক টাস্কে বিভক্ত হয়েছে - প্রতিটি ফাংশনের জন্য একটি।
saveSettings() ফাংশন এখন তার চাইল্ড ফাংশনগুলিকে আলাদা টাস্ক হিসাবে চালায়।

একটি ডেডিকেটেড সময়সূচী API

setTimeout হল কার্যগুলি ভাঙার একটি কার্যকর উপায়, তবে এটির একটি ত্রুটি থাকতে পারে: আপনি যখন পরবর্তী টাস্কে চালানোর জন্য কোডটি বিলম্বিত করে মূল থ্রেডে যোগ দেন, তখন সেই টাস্কটি সারির শেষে যোগ করা হয়।

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

ব্রাউজার সমর্থন

  • ক্রোম: 94।
  • প্রান্ত: 94।
  • ফায়ারফক্স: একটি পতাকার পিছনে।
  • সাফারি: সমর্থিত নয়।

উৎস

শিডিউলার এপিআই postTask() ফাংশন অফার করে যা কাজের সূক্ষ্ম সময়সূচীর জন্য অনুমতি দেয় এবং ব্রাউজারকে কাজের অগ্রাধিকার দিতে সাহায্য করার একটি উপায় যাতে কম অগ্রাধিকারের কাজগুলি মূল থ্রেডে আসে। postTask() প্রতিশ্রুতি ব্যবহার করে, এবং তিনটি priority সেটিংসের একটি গ্রহণ করে:

  • সর্বনিম্ন অগ্রাধিকারমূলক কাজের জন্য 'background'
  • মাঝারি অগ্রাধিকারমূলক কাজের জন্য 'user-visible' । কোন priority সেট না থাকলে এটি ডিফল্ট।
  • 'user-blocking' গুরুত্বপূর্ণ কাজগুলির জন্য যা উচ্চ অগ্রাধিকারে চালানো প্রয়োজন।

একটি উদাহরণ হিসাবে নিম্নলিখিত কোডটি নিন, যেখানে postTask() API সর্বোচ্চ সম্ভাব্য অগ্রাধিকারে তিনটি কাজ চালানোর জন্য এবং বাকি দুটি কাজ সর্বনিম্ন সম্ভাব্য অগ্রাধিকারে চালানোর জন্য ব্যবহৃত হয়।

function saveSettings () {
  // Validate the form at high priority
  scheduler.postTask(validateForm, {priority: 'user-blocking'});

  // Show the spinner at high priority:
  scheduler.postTask(showSpinner, {priority: 'user-blocking'});

  // Update the database in the background:
  scheduler.postTask(saveToDatabase, {priority: 'background'});

  // Update the user interface at high priority:
  scheduler.postTask(updateUI, {priority: 'user-blocking'});

  // Send analytics data in the background:
  scheduler.postTask(sendAnalytics, {priority: 'background'});
};

এখানে, কাজগুলির অগ্রাধিকার এমনভাবে নির্ধারিত হয় যাতে ব্রাউজার-অগ্রাধিকারযুক্ত কাজগুলি-যেমন ব্যবহারকারীর মিথস্ক্রিয়া-প্রয়োজন অনুসারে তাদের মধ্যে কাজ করতে পারে।

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

postTask() কীভাবে ব্যবহার করা যেতে পারে তার এটি একটি সরল উদাহরণ। বিভিন্ন TaskController অবজেক্টগুলিকে ইনস্ট্যান্ট করা সম্ভব যা প্রয়োজন অনুসারে বিভিন্ন TaskController দৃষ্টান্তগুলির জন্য অগ্রাধিকার পরিবর্তন করার ক্ষমতা সহ কাজের মধ্যে অগ্রাধিকার ভাগ করতে পারে।

scheduler.yield() API ব্যবহার করে ধারাবাহিকতা সহ অন্তর্নির্মিত ফলন

ব্রাউজার সমর্থন

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

উৎস

scheduler.yield() একটি API বিশেষভাবে ব্রাউজারে প্রধান থ্রেড প্রদানের জন্য ডিজাইন করা হয়েছে। এর ব্যবহার yieldToMain() ফাংশনের সাথে সাদৃশ্যপূর্ণ যা এই নির্দেশিকাতে পূর্বে প্রদর্শিত হয়েছে:

async function saveSettings () {
  // Create an array of functions to run:
  const tasks = [
    validateForm,
    showSpinner,
    saveToDatabase,
    updateUI,
    sendAnalytics
  ]

  // Loop over the tasks:
  while (tasks.length > 0) {
    // Shift the first task off the tasks array:
    const task = tasks.shift();

    // Run the task:
    task();

    // Yield to the main thread with the scheduler
    // API's own yielding mechanism:
    await scheduler.yield();
  }
}

এই কোডটি মূলত পরিচিত, কিন্তু yieldToMain() ব্যবহার করার পরিবর্তে, এটি await scheduler.yield() ব্যবহার করে।

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

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

isInputPending() ব্যবহার করবেন না

ব্রাউজার সমর্থন

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

উৎস

isInputPending() API একজন ব্যবহারকারী একটি পৃষ্ঠার সাথে ইন্টারঅ্যাক্ট করার চেষ্টা করেছে কিনা তা পরীক্ষা করার একটি উপায় প্রদান করে এবং যদি একটি ইনপুট মুলতুবি থাকে তবেই ফল দেয়।

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

যাইহোক, সেই API চালু হওয়ার পর থেকে, ফলন সম্পর্কে আমাদের বোঝা বেড়েছে, বিশেষ করে INP প্রবর্তনের মাধ্যমে। আমরা আর এই API ব্যবহার করার পরামর্শ দিই না , এবং পরিবর্তে বিভিন্ন কারণে ইনপুট মুলতুবি থাকুক বা না থাকুক না কেন ফলন দেওয়ার সুপারিশ করি:

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

উপসংহার

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

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

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

ফিলিপ ওয়ালটনকে বিশেষ ধন্যবাদ তার এই নির্দেশিকাটির প্রযুক্তিগত পরীক্ষা করার জন্য।

থাম্বনেইল ছবি আনস্প্ল্যাশ থেকে নেওয়া, আমিরালি মিরহাশেমিয়ানের সৌজন্যে।