১. ভূমিকা
ইন্টারঅ্যাকশন টু নেক্সট পেইন্ট (INP) সম্পর্কে শেখার জন্য একটি ইন্টারেক্টিভ ডেমো এবং কোডল্যাব।
পূর্বশর্ত
- এইচটিএমএল এবং জাভাস্ক্রিপ্ট ডেভেলপমেন্টের জ্ঞান।
- পরামর্শ দেওয়া হচ্ছে: INP ডকুমেন্টেশনটি পড়ুন।
আপনি যা শিখবেন
- ব্যবহারকারীর কার্যকলাপ এবং আপনার সেই কার্যকলাপ পরিচালনার পারস্পরিক সম্পর্ক কীভাবে পেজের রেসপন্সিভনেসকে প্রভাবিত করে।
- ব্যবহারকারীর মসৃণ অভিজ্ঞতার জন্য বিলম্ব কীভাবে কমানো ও দূর করা যায়।
আপনার যা প্রয়োজন
- এমন একটি কম্পিউটার যা গিটহাব থেকে কোড ক্লোন করতে এবং এনপিএম কমান্ড চালাতে সক্ষম।
- একটি টেক্সট এডিটর।
- সমস্ত ইন্টারঅ্যাকশন পরিমাপ সঠিকভাবে কাজ করার জন্য ক্রোমের একটি সাম্প্রতিক সংস্করণ প্রয়োজন।
২. প্রস্তুত হন
কোডটি নিন এবং চালান
কোডটি web-vitals-codelabs রিপোজিটরিতে পাওয়া যায়।
- আপনার টার্মিনালে রিপোটি ক্লোন করুন:
git clone https://github.com/GoogleChromeLabs/web-vitals-codelabs.git - ক্লোন করা ডিরেক্টরিতে প্রবেশ করুন:
cd web-vitals-codelabs/understanding-inp - নির্ভরতা ইনস্টল করুন:
npm ci - ওয়েব সার্ভার চালু করুন:
npm run start - আপনার ব্রাউজারে http://localhost:5173/understanding-inp/ ভিজিট করুন
অ্যাপটির সংক্ষিপ্ত বিবরণ
পেজের একেবারে উপরে একটি স্কোর কাউন্টার এবং ইনক্রিমেন্ট বাটন রয়েছে। এটি রিঅ্যাকটিভিটি এবং রেসপন্সিভনেসের একটি চমৎকার উদাহরণ!

বাটনটির নিচে চারটি পরিমাপ রয়েছে:
- INP: বর্তমান INP স্কোর, যা সাধারণত সবচেয়ে খারাপ মিথস্ক্রিয়াকে বোঝায়।
- মিথস্ক্রিয়া: সর্বশেষ মিথস্ক্রিয়ার স্কোর।
- FPS: পেজটির প্রধান থ্রেডের ফ্রেম-প্রতি-সেকেন্ড।
- টাইমার: জ্যাঙ্ক ভালোভাবে দেখানোর জন্য একটি চলমান টাইমার অ্যানিমেশন।
ইন্টারঅ্যাকশন পরিমাপের জন্য FPS এবং টাইমার এন্ট্রিগুলো মোটেও প্রয়োজনীয় নয়। রেসপন্সিভনেসকে আরেকটু সহজে দৃশ্যমান করার জন্যই কেবল এগুলো যোগ করা হয়েছে।
চেষ্টা করে দেখুন
ইনক্রিমেন্ট বাটনটির সাথে ইন্টারঅ্যাক্ট করে স্কোর বাড়তে দেখুন। প্রতিটি ইনক্রিমেন্টের সাথে কি INP এবং ইন্টারঅ্যাকশন ভ্যালুগুলো পরিবর্তিত হয়?
ব্যবহারকারীর ইন্টারঅ্যাকশনের মুহূর্ত থেকে শুরু করে পেজটিতে রেন্ডার করা আপডেটটি প্রদর্শিত হওয়া পর্যন্ত কতক্ষণ সময় লাগে, তা INP পরিমাপ করে।
৩. ক্রোম ডেভটুলস-এর সাথে মিথস্ক্রিয়া পরিমাপ করা
More Tools > Developer Tools মেনু থেকে, পেজটিতে রাইট-ক্লিক করে Inspect নির্বাচন করে , অথবা কিবোর্ড শর্টকাট ব্যবহার করে DevTools খুলুন ।
পারফরম্যান্স প্যানেলে যান, যেটি আপনি ইন্টারঅ্যাকশন পরিমাপ করতে ব্যবহার করবেন।

এরপরে, পারফরম্যান্স প্যানেলে একটি ইন্টারঅ্যাকশন ক্যাপচার করুন।
- প্রেস রেকর্ড।
- পৃষ্ঠাটির সাথে ইন্টারঅ্যাক্ট করুন ( ইনক্রিমেন্ট বাটনটি চাপুন)।
- রেকর্ডিং বন্ধ করুন।
ফলস্বরূপ টাইমলাইনে, আপনি একটি ইন্টারঅ্যাকশনস ট্র্যাক পাবেন। বাম দিকের ত্রিভুজটিতে ক্লিক করে এটিকে প্রসারিত করুন।

দুটি ইন্টারঅ্যাকশন দেখা যাবে। স্ক্রোল করে অথবা W কী চেপে ধরে দ্বিতীয়টিতে জুম ইন করুন।

ইন্টারঅ্যাকশনটির উপর মাউস রাখলে আপনি দেখতে পাবেন যে, ইন্টারঅ্যাকশনটি দ্রুত ছিল; এটি প্রসেসিং- এ কোনো সময় ব্যয় করেনি এবং ইনপুট ডিলে ও প্রেজেন্টেশন ডিলে- তে ন্যূনতম সময় নিয়েছে, যেগুলোর সঠিক দৈর্ঘ্য আপনার মেশিনের গতির উপর নির্ভর করবে।
৪. দীর্ঘস্থায়ী ইভেন্ট শ্রোতা
index.js ফাইলটি খুলুন এবং ইভেন্ট লিসেনারের ভিতরে থাকা blockFor ফাংশনটির কমেন্ট তুলে দিন।
সম্পূর্ণ কোড দেখুন: click_block.html
button.addEventListener('click', () => {
blockFor(1000);
score.incrementAndUpdateUI();
});
ফাইলটি সংরক্ষণ করুন। সার্ভার পরিবর্তনটি দেখতে পাবে এবং আপনার জন্য পৃষ্ঠাটি রিফ্রেশ করে দেবে।
পৃষ্ঠাটির সাথে আবার ইন্টারঅ্যাক্ট করার চেষ্টা করুন। এখন ইন্টারঅ্যাকশনগুলো লক্ষণীয়ভাবে ধীর হবে।
পারফরম্যান্স ট্রেস
পারফরম্যান্স প্যানেলে এটি কেমন দেখায় তা দেখতে আরও একটি রেকর্ডিং করুন।

যে আলাপচারিতা একসময় সংক্ষিপ্ত ছিল, এখন তাতে পুরো এক সেকেন্ড সময় লাগে।
যখন আপনি ইন্টারঅ্যাকশনটির উপর মাউস নিয়ে যাবেন, তখন লক্ষ্য করুন যে প্রায় পুরো সময়টাই "প্রসেসিং ডিউরেশন"-এ ব্যয় হয়, যা হলো ইভেন্ট লিসেনার কলব্যাকগুলো কার্যকর করতে প্রয়োজনীয় সময়। যেহেতু ব্লকিং blockFor কলটি সম্পূর্ণভাবে ইভেন্ট লিসেনারের মধ্যেই থাকে, তাই সময়টা সেখানেই ব্যয় হয়।
৫. পরীক্ষা: প্রক্রিয়াকরণের সময়কাল
INP-এর উপর এর প্রভাব দেখতে ইভেন্ট-লিসেনারের কাজ পুনর্বিন্যাস করার বিভিন্ন উপায় পরীক্ষা করে দেখুন।
প্রথমে UI আপডেট করুন
js কলগুলোর ক্রম উল্টে দিলে কী হবে—প্রথমে UI আপডেট করে, তারপর ব্লক করলে?
সম্পূর্ণ কোড দেখুন: ui_first.html
button.addEventListener('click', () => {
score.incrementAndUpdateUI();
blockFor(1000);
});
আপনি কি লক্ষ্য করেছেন যে UI আগে প্রদর্শিত হয়েছে? ক্রমটি কি INP স্কোরকে প্রভাবিত করে?
একটি ট্রেস নিয়ে মিথস্ক্রিয়াটি পরীক্ষা করে দেখুন কোনো পার্থক্য ছিল কিনা।
পৃথক শ্রোতা
কাজটি একটি আলাদা ইভেন্ট লিসেনারে সরিয়ে নিলে কেমন হয়? একটি ইভেন্ট লিসেনারে UI আপডেট করুন, এবং অন্য একটি লিসেনার থেকে পেজটি ব্লক করুন।
সম্পূর্ণ কোড দেখুন: two_click.html
button.addEventListener('click', () => {
score.incrementAndUpdateUI();
});
button.addEventListener('click', () => {
blockFor(1000);
});
পারফরম্যান্স প্যানেলে এখন এটি দেখতে কেমন লাগছে?
বিভিন্ন ধরণের ইভেন্ট
বেশিরভাগ ইন্টারঅ্যাকশন বিভিন্ন ধরণের ইভেন্ট ট্রিগার করে, যেমন পয়েন্টার বা কী ইভেন্ট, হোভার, ফোকাস/ব্লার এবং বিফোরচেঞ্জ ও বিফোরইনপুটের মতো সিন্থেটিক ইভেন্ট।
অনেক আসল পেজেই বিভিন্ন অনুষ্ঠানের জন্য শ্রোতা থাকে।
ইভেন্ট লিসেনারগুলোর ইভেন্ট টাইপ পরিবর্তন করলে কী হবে? উদাহরণস্বরূপ, click ইভেন্ট লিসেনারগুলোর একটিকে pointerup বা mouseup দিয়ে প্রতিস্থাপন করলে কী হবে?
সম্পূর্ণ কোড দেখুন: diff_handlers.html
button.addEventListener('click', () => {
score.incrementAndUpdateUI();
});
button.addEventListener('pointerup', () => {
blockFor(1000);
});
কোন UI আপডেট নেই
ইভেন্ট লিসেনার থেকে UI আপডেট করার কলটি সরিয়ে দিলে কী হবে?
সম্পূর্ণ কোড দেখুন: no_ui.html
button.addEventListener('click', () => {
blockFor(1000);
// score.incrementAndUpdateUI();
});
৬. প্রক্রিয়াকরণের সময়কাল পরীক্ষার ফলাফল
পারফরম্যান্স ট্রেস: প্রথমে UI আপডেট করুন
সম্পূর্ণ কোড দেখুন: ui_first.html
button.addEventListener('click', () => {
score.incrementAndUpdateUI();
blockFor(1000);
});
বাটনটি ক্লিক করার পারফরম্যান্স প্যানেলের রেকর্ডিং দেখলে আপনি দেখতে পাবেন যে, ফলাফলে কোনো পরিবর্তন আসেনি। যদিও ব্লকিং কোডের আগে একটি UI আপডেট ট্রিগার হয়েছিল, ইভেন্ট লিসেনারটি সম্পূর্ণ না হওয়া পর্যন্ত ব্রাউজারটি স্ক্রিনে যা দেখানো হচ্ছিল তা আসলে আপডেট করেনি, যার মানে হলো ইন্টারঅ্যাকশনটি সম্পূর্ণ হতে তখনও এক সেকেন্ডের কিছু বেশি সময় লেগেছিল।

পারফরম্যান্স ট্রেস: পৃথক লিসেনার
সম্পূর্ণ কোড দেখুন: two_click.html
button.addEventListener('click', () => {
score.incrementAndUpdateUI();
});
button.addEventListener('click', () => {
blockFor(1000);
});
আবার, কার্যগতভাবে কোনো পার্থক্য নেই। মিথস্ক্রিয়াটি সম্পন্ন হতে এখনও পুরো এক সেকেন্ড সময় লাগে।
আপনি যদি ক্লিক ইন্টারঅ্যাকশনটি ভালোভাবে দেখেন, তাহলে দেখতে পাবেন যে click ইভেন্টের ফলে প্রকৃতপক্ষে দুটি ভিন্ন ফাংশন কল করা হচ্ছে।
যেমনটা আশা করা হয়েছিল, প্রথমটি—ইউআই আপডেট করা—অবিশ্বাস্যভাবে দ্রুত সম্পন্ন হয়, যেখানে দ্বিতীয়টিতে পুরো এক সেকেন্ড সময় লাগে। তবে, এগুলোর সম্মিলিত প্রভাবে চূড়ান্ত ব্যবহারকারীর জন্য অভিজ্ঞতাটি একই রকম ধীরগতির হয়।

পারফরম্যান্স ট্রেস: বিভিন্ন ইভেন্টের ধরণ
button.addEventListener('click', () => {
score.incrementAndUpdateUI();
});
button.addEventListener('pointerup', () => {
blockFor(1000);
});
এই ফলাফলগুলো খুবই সাদৃশ্যপূর্ণ। ইন্টারঅ্যাকশনটি এখনও পুরো এক সেকেন্ডের; একমাত্র পার্থক্য হলো, সংক্ষিপ্ততর এবং শুধুমাত্র UI-আপডেট-ভিত্তিক click লিসেনারটি এখন ব্লকিং pointerup লিসেনারের পরে চলে।

পারফরম্যান্স ট্রেস: কোন UI আপডেট নেই
সম্পূর্ণ কোড দেখুন: no_ui.html
button.addEventListener('click', () => {
blockFor(1000);
// score.incrementAndUpdateUI();
});
- স্কোর আপডেট হয় না, কিন্তু পেজটি ঠিকই দেখা যায়!
- অ্যানিমেশন, সিএসএস এফেক্ট, ডিফল্ট ওয়েব কম্পোনেন্ট অ্যাকশন (ফর্ম ইনপুট), টেক্সট এন্ট্রি, টেক্সট হাইলাইটিং—সবকিছু ক্রমাগত আপডেট হতে থাকে।
এক্ষেত্রে বাটনটি ক্লিক করলে সক্রিয় অবস্থায় যায় এবং আবার আগের অবস্থায় ফিরে আসে, যার জন্য ব্রাউজারকে রঙ করতে হয়, যার মানে এখানে এখনও একটি INP রয়েছে।
যেহেতু ইভেন্ট লিসেনারটি এক সেকেন্ডের জন্য মেইন থ্রেডকে ব্লক করে পেজটিকে পেইন্ট হতে বাধা দিচ্ছিল, তাই ইন্টারঅ্যাকশনটি সম্পন্ন হতে পুরো এক সেকেন্ড সময় লাগে।
পারফরম্যান্স প্যানেলের রেকর্ডিং নিলে দেখা যায় যে, পারস্পরিক আলোচনাটি আগেরগুলোর মতোই প্রায় হুবহু একই।

টেকঅ্যাওয়ে
যেকোনো ইভেন্ট লিসেনারে চলমান যেকোনো কোড ইন্টারঅ্যাকশনকে বিলম্বিত করবে।
- এর মধ্যে বিভিন্ন স্ক্রিপ্ট থেকে নিবন্ধিত লিসেনার এবং লিসেনারের মধ্যে চালিত ফ্রেমওয়ার্ক বা লাইব্রেরি কোড অন্তর্ভুক্ত, যেমন একটি স্টেট আপডেট যা একটি কম্পোনেন্ট রেন্ডারকে ট্রিগার করে।
- শুধু আপনার নিজের কোডই নয়, সমস্ত থার্ড-পার্টি স্ক্রিপ্টও।
এটা একটা সাধারণ সমস্যা!
পরিশেষে: আপনার কোড কোনো পেইন্ট ট্রিগার না করলেও, তার মানে এই নয় যে পেইন্টটি ধীরগতির ইভেন্ট লিসেনারগুলোর কাজ শেষ হওয়ার জন্য অপেক্ষা করবে না।
৭. পরীক্ষা: ইনপুট বিলম্ব
ইভেন্ট লিসেনারের বাইরে দীর্ঘক্ষণ ধরে চলা কোডের ক্ষেত্রে কী হবে? উদাহরণস্বরূপ:
- যদি আপনার এমন কোনো
<script>থাকতো যা দেরিতে লোড হতো এবং লোড হওয়ার সময় হুট করে পেজটিকে আটকে দিত। -
setIntervalমতো কোনো এপিআই কল, যা পর্যায়ক্রমে পেজটিকে ব্লক করে রাখে?
ইভেন্ট লিসেনার থেকে blockFor সরিয়ে দিয়ে এটিকে setInterval() এ যোগ করার চেষ্টা করুন:
সম্পূর্ণ কোড দেখুন: input_delay.html
setInterval(() => {
blockFor(1000);
}, 3000);
button.addEventListener('click', () => {
score.incrementAndUpdateUI();
});
কী ঘটে?
৮. ইনপুট বিলম্ব পরীক্ষার ফলাফল
সম্পূর্ণ কোড দেখুন: input_delay.html
setInterval(() => {
blockFor(1000);
}, 3000);
button.addEventListener('click', () => {
score.incrementAndUpdateUI();
});
setInterval ব্লকিং টাস্কটি চলার সময় কোনো বাটন ক্লিক রেকর্ড করলে, সেই ইন্টারঅ্যাকশনে কোনো ব্লকিং কাজ না হওয়া সত্ত্বেও একটি দীর্ঘস্থায়ী ইন্টারঅ্যাকশন তৈরি হয়!
এই দীর্ঘস্থায়ী সময়কালগুলোকে প্রায়শই দীর্ঘ কাজ বলা হয়।
DevTools-এ ইন্টারঅ্যাকশনটির উপর মাউস রাখলে আপনি দেখতে পাবেন যে, ইন্টারঅ্যাকশনের সময় এখন প্রধানত ইনপুট বিলম্বের কারণে নির্ধারিত হয়, প্রসেসিং সময়কালের কারণে নয়।

লক্ষ্য করুন, এটি সবসময় ইন্টারঅ্যাকশনকে প্রভাবিত করে না! টাস্কটি চলার সময় আপনি যদি ক্লিক না করেন, তাহলে আপনার ভাগ্য ভালো থাকতে পারে। এই ধরনের "হঠাৎ" ঘটা সমস্যাগুলো ডিবাগ করা দুঃস্বপ্নের মতো হতে পারে, বিশেষ করে যখন এগুলো কেবল মাঝে মাঝে সমস্যা সৃষ্টি করে।
এগুলো খুঁজে বের করার একটি উপায় হলো দীর্ঘ টাস্ক (বা দীর্ঘ অ্যানিমেশন ফ্রেম ) এবং মোট ব্লকিং টাইম পরিমাপ করা।
৯. ধীর উপস্থাপনা
এখন পর্যন্ত আমরা ইনপুট ডিলে বা ইভেন্ট লিসেনারের মাধ্যমে জাভাস্ক্রিপ্টের পারফরম্যান্স দেখেছি, কিন্তু পরবর্তী পেইন্ট রেন্ডারিংকে আর কী কী প্রভাবিত করে?
আচ্ছা, দামী ইফেক্ট দিয়ে পেজটা আপডেট করা হচ্ছে!
পৃষ্ঠাটি দ্রুত আপডেট হলেও, সেগুলোকে রেন্ডার করতে ব্রাউজারকে বেশ পরিশ্রম করতে হতে পারে!
মূল থ্রেডে:
- UI ফ্রেমওয়ার্ক যেগুলোকে অবস্থার পরিবর্তনের পর আপডেট রেন্ডার করতে হয়
- DOM-এর পরিবর্তন, অথবা অনেক ব্যয়বহুল CSS কোয়েরি সিলেক্টর টগল করার ফলে প্রচুর Style, Layout, এবং Paint ট্রিগার হতে পারে।
মূল আলোচনার বাইরে:
- GPU ইফেক্টকে শক্তিশালী করতে CSS ব্যবহার করা
- খুব বড় উচ্চ-রেজোলিউশনের ছবি যোগ করা
- SVG/ক্যানভাস ব্যবহার করে জটিল দৃশ্য আঁকা

ওয়েবে সচরাচর পাওয়া যায় এমন কিছু উদাহরণ:
- একটি SPA সাইট যা কোনো লিঙ্কে ক্লিক করার পর প্রাথমিক ভিজ্যুয়াল ফিডব্যাক দেওয়ার জন্য বিরতি না নিয়েই সম্পূর্ণ DOM পুনর্নির্মাণ করে।
- একটি সার্চ পেজ যা ডাইনামিক ইউজার ইন্টারফেস সহ জটিল সার্চ ফিল্টার প্রদান করে, কিন্তু তা করার জন্য ব্যয়বহুল লিসেনার চালায়।
- একটি ডার্ক মোড টগল যা পুরো পৃষ্ঠার স্টাইল/লেআউট চালু করে।
১০. পরীক্ষা: উপস্থাপনায় বিলম্ব
ধীর requestAnimationFrame
চলুন requestAnimationFrame() API ব্যবহার করে একটি দীর্ঘ প্রেজেন্টেশন বিলম্ব অনুকরণ করি।
blockFor কলটিকে একটি requestAnimationFrame কলব্যাকে সরিয়ে নিন, যাতে এটি ইভেন্ট লিসেনার রিটার্ন করার পরে চলে:
সম্পূর্ণ কোড দেখুন: presentation_delay.html
button.addEventListener('click', () => {
score.incrementAndUpdateUI();
requestAnimationFrame(() => {
blockFor(1000);
});
});
কী ঘটে?
১১. উপস্থাপনা বিলম্ব পরীক্ষার ফলাফল
সম্পূর্ণ কোড দেখুন: presentation_delay.html
button.addEventListener('click', () => {
score.incrementAndUpdateUI();
requestAnimationFrame(() => {
blockFor(1000);
});
});
কথোপকথনটি এক সেকেন্ড স্থায়ী হয়, তাহলে কী ঘটল?
requestAnimationFrame পরবর্তী পেইন্টের আগে একটি কলব্যাক অনুরোধ করে। যেহেতু INP ইন্টারঅ্যাকশন থেকে পরবর্তী পেইন্ট পর্যন্ত সময় পরিমাপ করে, তাই requestAnimationFrame এর blockFor(1000) পরবর্তী পেইন্টকে পুরো এক সেকেন্ডের জন্য ব্লক করে রাখে।

তবে, দুটি বিষয় লক্ষ্য করুন:
- হোভার করলে আপনি দেখতে পাবেন যে, ইন্টারঅ্যাকশনের সম্পূর্ণ সময় এখন "প্রেজেন্টেশন ডিলে"-তে ব্যয় হচ্ছে, কারণ ইভেন্ট লিসেনার রিটার্ন করার পরে মেইন-থ্রেড ব্লকিং ঘটছে।
- মেইন-থ্রেড অ্যাক্টিভিটির রুট এখন আর ক্লিক ইভেন্ট নয়, বরং "অ্যানিমেশন ফ্রেম ফায়ার্ড"।
১২. মিথস্ক্রিয়া নির্ণয়
এই টেস্ট পেজটিতে, স্কোর, টাইমার এবং কাউন্টার UI-এর কারণে রেসপন্সিভনেস অত্যন্ত দৃশ্যমান... কিন্তু সাধারণ পেজ পরীক্ষা করার সময় এটি আরও সূক্ষ্ম।
যখন আলাপচারিতা দীর্ঘায়িত হয়, তখন এর কারণটা সবসময় স্পষ্ট বোঝা যায় না। এর কারণ কি:
- ইনপুট বিলম্ব?
- ইভেন্ট প্রক্রিয়াকরণের সময়কাল?
- উপস্থাপনায় বিলম্ব?
আপনার ইচ্ছামত যেকোনো পেজে রেসপন্সিভনেস পরিমাপ করতে আপনি ডেভটুলস ব্যবহার করতে পারেন। এই অভ্যাসটি গড়ে তুলতে, এই পদ্ধতিটি অনুসরণ করুন:
- আপনি স্বাভাবিকভাবেই ওয়েব ব্যবহার করুন।
- DevTools পারফরম্যান্স প্যানেলের লাইভ মেট্রিক্স ভিউতে থাকা ইন্টারঅ্যাকশন লগটির ওপর নজর রাখুন।
- যদি আপনি কোনো ত্রুটিপূর্ণ ইন্টারঅ্যাকশন দেখতে পান, তবে সেটি পুনরাবৃত্তি করার চেষ্টা করুন:
- যদি আপনি এটি পুনরাবৃত্তি করতে না পারেন, তাহলে বিস্তারিত তথ্য পেতে ইন্টারঅ্যাকশন লগ ব্যবহার করুন।
- আপনি যদি এটি পুনরাবৃত্তি করতে পারেন, তাহলে পারফরম্যান্স প্যানেলে একটি ট্রেস রেকর্ড করুন।
সমস্ত বিলম্ব
পৃষ্ঠাটিতে এই সমস্যাগুলোর কিছু কিছু যোগ করার চেষ্টা করুন:
সম্পূর্ণ কোড দেখুন: all_the_things.html
setInterval(() => {
blockFor(1000);
}, 3000);
button.addEventListener('click', () => {
blockFor