Q148: Task Queues, Job Queues and Cooperative Scheduling
What Interviewers Want To Evaluate
This question checks whether you can keep JavaScript responsive under heavy work. Interviewers want task queues, microtask jobs, yielding, chunking, cooperative scheduling, long tasks, workers, idle callbacks, and user input responsiveness.
Senior answers should connect scheduling decisions to INP and real product workflows.
Short Interview Answer
JavaScript runs on a single main thread in the browser, so long synchronous work blocks input and rendering. Tasks run one at a time, and promise jobs or microtasks drain before the browser moves on. Cooperative scheduling means breaking large work into chunks and yielding back to the browser so it can handle input and paint. Heavy CPU work should often move to a Web Worker, while low-priority work can be delayed or chunked.
Detailed Interview Answer
The main thread is shared by:
JavaScript execution
style calculation
layout
paint coordination
input handling
event callbacks
If JavaScript monopolizes the thread, the UI feels frozen.
Long Tasks
A long task is a task that blocks the main thread long enough to hurt responsiveness.
Examples:
large JSON processing
client-side filtering of huge arrays
syntax highlighting large files
spreadsheet calculations
rendering thousands of rows
image processing
Long tasks can increase INP and make users feel the app is broken.
Microtask Caution
Microtasks run before the browser continues to rendering or the next task.
If code keeps scheduling microtasks, it can starve rendering.
function loop() {
queueMicrotask(loop);
}
Microtasks are not a general yielding mechanism for heavy work.
Chunking Work
Chunking splits work into smaller units.
function processInChunks(items, processItem) {
let index = 0;
function runChunk() {
const deadline = performance.now() + 8;
while (index < items.length && performance.now() < deadline) {
processItem(items[index]);
index += 1;
}
if (index < items.length) {
setTimeout(runChunk, 0);
}
}
runChunk();
}
This lets the browser breathe between chunks.
Yielding
Yielding means letting the browser process other work.
Common approaches:
setTimeout with small delay
requestAnimationFrame for visual work
requestIdleCallback for low-priority work where supported
scheduler APIs where available
awaiting a task-based delay
Choose based on urgency and browser support.
requestAnimationFrame
Use requestAnimationFrame for work that should happen before paint.
requestAnimationFrame(() => {
updateVisualPosition();
});
It aligns visual updates with the browser's rendering loop.
requestIdleCallback
requestIdleCallback can run low-priority work when the browser has idle time.
It is useful for:
non-critical precomputation
analytics batching
cache cleanup
preparing optional UI
Always have a fallback because support varies.
Web Workers
Move CPU-heavy work off the main thread.
const worker = new Worker("/worker.js");
worker.postMessage(data);
Workers help with heavy computation, but data transfer and serialization costs still matter.
Common Mistakes
A common mistake is chunking with microtasks and still blocking paint.
Another mistake is moving small work to a worker and paying more overhead than the work costs.
Another mistake is doing huge loops inside input handlers.
Senior Trade-Offs
Use chunking for medium work that can be split. Use workers for heavy CPU work. Use animation frames for visual updates. Use idle time for low-priority work.
Measure before and after because scheduling choices can shift cost rather than remove it.
Code or Design Example
function delayTask() {
return new Promise((resolve) => {
setTimeout(resolve, 0);
});
}
async function processWithYields(items, processItem) {
for (let index = 0; index < items.length; index += 1) {
processItem(items[index]);
if (index % 100 === 0) {
await delayTask();
}
}
}
This yields between groups of items.
Debugging Workflow
When responsiveness is poor:
record a performance trace
identify long tasks
locate heavy loops or parsing
check microtask chains
chunk medium work
move heavy work to workers
align visual work with requestAnimationFrame
measure INP and interaction timing
Interview Framing
Explain main-thread blocking, then discuss chunking, yielding, requestAnimationFrame, idle work, and workers.
Revision Notes
Cooperative scheduling means giving the browser chances to handle input and render.
Key Takeaways
Responsiveness is not only about faster code. It is also about letting the browser run at the right times.
Follow-Up Questions
- What is a long task?
- Why do long tasks hurt input responsiveness?
- Why are microtasks not ideal for yielding?
- What is work chunking?
- When should requestAnimationFrame be used?
- What is requestIdleCallback for?
- When should work move to a Web Worker?
- What costs do workers still have?
- How do you debug main-thread blocking?
- How does this relate to INP?
How I Would Answer This In A Real Interview
I would say long synchronous work blocks input and paint. I would split medium work into chunks, use animation frames for visual updates, idle callbacks for low-priority work, and workers for heavy CPU tasks, then verify with performance traces.