Senior #event-loop#microtask#performance#starvation
Microtask starvation là gì? Làm sao tránh chặn event loop?
⚡ Trả lời nhanh
Event loop chạy hết toàn bộ microtask queue (kể cả microtask mới sinh ra) trước khi sang macrotask hay render. Nếu microtask liên tục tự lên lịch microtask khác, timer, I/O và render bị bỏ đói (starvation) và trang đứng. Tránh bằng cách nhường quyền qua macrotask (`setTimeout`, `MessageChannel`, `scheduler.yield`).
Ví dụ
main.js · sửa được
Timer có hạn 0ms vẫn phải chờ 1000 microtask xong. Nếu điều kiện dừng không bao giờ đúng, vòng lặp là vô hạn và tab đóng băng, vì microtask queue không bao giờ cạn.
So với macrotask
- Sau mỗi macrotask, engine drain toàn bộ microtask, rồi mới có thể render và lấy macrotask tiếp theo.
- Đệ quy bằng
setTimeout(loop)thì ổn: giữa các vòng trình duyệt vẫn render và xử lý input. queueMicrotaskvàPromise.thencùng queue;awaittrên promise đã resolve cũng là microtask.
Cách tránh
- Chia việc nặng thành các lô nhỏ, nhường quyền giữa các lô bằng macrotask (
setTimeout,MessageChannel) hoặcscheduler.yield()ở trình duyệt hỗ trợ; Node dùngsetImmediate. - Với tác vụ CPU thật sự nặng, chuyển sang Web Worker/
worker_threads. requestIdleCallbackcho việc không gấp.