</>
⌕
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.
  • queueMicrotask và Promise.then cùng queue; await trê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ặc scheduler.yield() ở trình duyệt hỗ trợ; Node dùng setImmediate.
  • Với tác vụ CPU thật sự nặng, chuyển sang Web Worker/worker_threads.
  • requestIdleCallback cho việc không gấp.
🃏 Ôn bằng flashcard