Advanced Async (Event Loop 2.0) & Multithreading
"Breaking the Limits of Single Thread"
অধ্যায় ১৭-তে আমরা জেনেছি ইভেন্ট লুপ কীভাবে কাজ করে। কিন্তু রিয়েল ওয়ার্ল্ডে শুধু কাজ করাটাই শেষ কথা নয়। যদি তুমি ১০০০টা প্রমিজ চেইন করো, ব্রাউজার কেন হ্যাং করে? কিভাবে ভারী ক্যালকুলেশন মেইন থ্রেডের বাইরে পাঠানো যায়?
এই অধ্যায়ে আমরা জাভাস্ক্রিপ্টের "Scheduler" এবং "Multithreading" নিয়ে পোস্টমর্টেম করব।
⭐ ১. Microtask Starvation (The VIP Trap) ⚠️
Promise (Microtask) এর প্রায়োরিটি setTimeout (Macrotask) এর চেয়ে বেশি। কিন্তু এর একটা ভয়ঙ্কর দিক আছে।
❌ Dangerous Code (Browser Hang)
function blockUI() {
return Promise.resolve().then(() => {
console.log("Blocking...");
return blockUI(); // Recursive Microtask
});
}
// blockUI(); // 🛑 সাবধান! এটা চালালে ট্যাব ফ্রিজ হয়ে যাবে।
কেন ফ্রিজ হয়? কারণ ইভেন্ট লুপ Microtask শেষ করতে চায়, কিন্তু তুমি নতুন Microtask দিচ্ছ। ফলে ব্রাউজার আর Paint/Render করতে পারছে না।
✅ Safe Code (Macrotask)
function safeLoop() {
setTimeout(() => {
console.log("Breathing...");
safeLoop(); // Recursive Macrotask
}, 0);
}
// safeLoop(); // ✅ এটা নিরাপদ।
কেন নিরাপদ? কারণ প্রতিটি setTimeout এর মাঝখানে ব্রাউজার রেন্ডার করার সুযোগ পায়।
⭐ ২. Browser Rendering Cycle & The 16ms Budget ⏱️
ব্রাউজার সাধারণত 60 FPS (Frames Per Second) এ চলে। প্রতি ফ্রেমে ব্রাউজারের হাতে সময় থাকে মাত্র ১৬.৬৬ মিলি সেকেন্ড।
এই ১৬ মিলি সেকেন্ডের মধ্যে যা করতে হয়:
- Script: জাভাস্ক্রিপ্ট রান করা
- Style: CSS ক্যালকুলেশন
- Layout: এলিমেন্টের অবস্থান ঠিক করা
- Paint: পিক্সেল আঁকা
যদি জাভাস্ক্রিপ্ট রান করতে 200ms সময় নেয়, তাহলে 16ms এর বাজেট ফেল করবে → UI Lag বা Jank!
⭐ ৩. Scheduler API: কাজ ভাগ করে দেওয়া 📅
A) requestIdleCallback (অলস সময়ের কাজ)
requestIdleCallback((deadline) => {
while (deadline.timeRemaining() > 0 && tasks.length > 0) {
processTask(tasks.pop());
}
});
B) scheduler.postTask (The Future Standard) 🚀
// হাই প্রায়োরিটি (ক্লিক বা ইনপুট)
scheduler.postTask(() => console.log("User Input"), { priority: 'user-blocking' });
// নরমাল
scheduler.postTask(() => console.log("API Fetch"), { priority: 'user-visible' });
// লো প্রায়োরিটি (ব্যাকগ্রাউন্ড)
scheduler.postTask(() => console.log("Analytics"), { priority: 'background' });
⭐ ৪. Web Workers: True Multithreading 🧵
জাভাস্ক্রিপ্ট নিজে সিঙ্গেল থ্রেডেড, কিন্তু ব্রাউজার নয়। ভারী কাজ Web Worker-এ পাঠাও।
Worker Architecture:
- Main Thread: UI সামলায়, DOM এক্সেস করতে পারে
- Worker Thread: শুধু লজিক সামলায়, DOM এক্সেস করতে পারে না
- Communication: postMessage এবং onmessage দিয়ে কথা বলে
main.js (UI Thread)
const worker = new Worker("worker.js");
worker.postMessage(1000000000);
worker.onmessage = (e) => {
console.log("Total Sum:", e.data);
};
console.log("UI is still responsive!");
worker.js (Background Thread)
onmessage = (e) => {
const limit = e.data;
let sum = 0;
for (let i = 0; i < limit; i++) sum += i;
postMessage(sum);
};
⭐ ৫. Service Workers & PWA (Brief Intro) 📡
Web Worker এর একটি বিশেষ রূপ হলো Service Worker। এটি Network Proxy হিসেবে কাজ করে এবং অফলাইনে অ্যাপ চালায় (PWA)।
- অ্যাপ এবং ইন্টারনেটের মাঝখানে দাঁড়িয়ে থাকে
- ইন্টারনেট না থাকলে Cache থেকে পেজ লোড করে দেয়
- ব্যাকগ্রাউন্ড সিঙ্ক এবং পুশ নোটিফিকেশন হ্যান্ডেল করে
🧠 ৬. Senior Level Interview Questions
Q1: Promise লুপ কেন setTimeout লুপের চেয়ে বিপজ্জনক?
উত্তর: Promise হলো Microtask। ইভেন্ট লুপ Microtask Queue খালি না হওয়া পর্যন্ত রেন্ডার করে না → Browser Hang (Starvation)।
Q2: Web Worker কি DOM এক্সেস করতে পারে?
উত্তর: না। DOM নট-থ্রেড-সেফ। Worker শুধু ডাটা প্রসেস করে Main Thread-এ পাঠায়।
Q3: requestAnimationFrame এবং requestIdleCallback এর পার্থক্য কী?
উত্তর: rAF → হাই প্রায়োরিটি ভিজ্যুয়াল আপডেট (প্রতি ফ্রেমে)। rIdleCallback → লো প্রায়োরিটি ব্যাকগ্রাউন্ড কাজ।
🚀 অধ্যায় ২৪ সারাংশ (Checklist)
- ✓Risk: Microtask Starvation কিভাবে UI ব্লক করে
- ✓Budget: 16ms এর মধ্যে কাজ শেষ করার চ্যালেঞ্জ
- ✓Scheduling: requestIdleCallback দিয়ে অলস সময়ে কাজ করানো
- ✓Multithreading: Web Workers দিয়ে ভারী কাজ ব্যাকগ্রাউন্ডে পাঠানো
Next Step: আমরা জাভাস্ক্রিপ্টের পারফরম্যান্স এবং ইন্টারনাল আর্কিটেকচার পুরোপুরি শিখে ফেলেছি। এখন প্র্যাকটিক্যাল প্রজেক্টের দিকে যাব! 🎯