Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 75 additions & 61 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,73 +27,87 @@ This document is a developer-oriented description of what event loop does. It tr

This is what the spec says:

eventLoop = {
taskQueues: {
events: [], // UI events from native GUI framework
parser: [], // HTML parser
callbacks: [], // setTimeout, requestIdleTask
resources: [], // image loading
domManipulation[]
},

microtaskQueue: [
],

nextTask: function() {
// Spec says:
// "Select the oldest task on one of the event loop's task queues"
// Which gives browser implementers lots of freedom
// Queues can have different priorities, etc.
for (let q of taskQueues)
if (q.length > 0)
return q.shift();
return null;
},

executeMicrotasks: function() {
if (scriptExecuting)
return;
let microtasks = this.microtaskQueue;
this.microtaskQueue = [];
for (let t of microtasks)
t.execute();
},

needsRendering: function() {
return vSyncTime() && (needsDomRerender() || hasEventLoopEventsToDispatch());
},

render: function() {
dispatchPendingUIEvents();
resizeSteps();
scrollSteps();
mediaQuerySteps();
cssAnimationSteps();
fullscreenRenderingSteps();

animationFrameCallbackSteps();

intersectionObserverSteps();

while (resizeObserverSteps()) {
updateStyle();
updateLayout();
}
paint();
```js
eventLoop = {
taskQueues: {
events: [], // UI events from native GUI framework
parser: [], // HTML parser
callbacks: [], // setTimeout, requestIdleTask
resources: [], // image loading
domManipulation[]
},

microtaskQueue: [
],

requestAnimationFrameQueue: [
],

nextTask() {
// Spec says:
// "Select the oldest task on one of the event loop's task queues"
// Which gives browser implementers lots of freedom
// Queues can have different priorities, etc.
for (let q of taskQueues)
if (q.length > 0)
return q.shift();
return null;
},

executeJSCallback(callback) {
callback();
if (!scriptExecuting) this.executeMicrotasks();
},

executeMicrotasks() {
let microTask;

while (microtask = this.microtaskQueue.shift()) {
microTask.execute();
}
},

executeRequestAnimationFrameCallbacks() {
const callbacks = this.requestAnimationFrameQueue;
this.requestAnimationFrameQueue = [];

for (const callback of callbacks) this.executeJSCallback(callback);
}

while(true) {
task = eventLoop.nextTask();
if (task) {
task.execute();
needsRendering() {
return vSyncTime() && (needsDomRerender() || hasEventLoopEventsToDispatch());
},

render() {
dispatchPendingUIEvents();
resizeSteps();
scrollSteps();
mediaQuerySteps();
cssAnimationSteps();
fullscreenRenderingSteps();

this.executeRequestAnimationFrameCallbacks();

intersectionObserverSteps();

while (resizeObserverSteps()) {
updateStyle();
updateLayout();
}
eventLoop.executeMicrotasks();
if (eventLoop.needsRendering())
eventLoop.render();
paint();
}
}


while(true) {
task = eventLoop.nextTask();
if (task) {
task.execute();
}
eventLoop.executeMicrotasks();
if (eventLoop.needsRendering())
eventLoop.render();
}
```

## Close reading of the spec

Expand Down