From 9427d9b3f929d96aa9ca58e0d8031b7fdd3abf4f Mon Sep 17 00:00:00 2001 From: Jake Archibald Date: Tue, 26 Sep 2017 14:04:25 +0100 Subject: [PATCH 1/2] Fixing microtasks and fleshing out raf --- README.md | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 8ba43f0..33c2592 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ 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 @@ -39,7 +40,10 @@ This is what the spec says: microtaskQueue: [ ], - nextTask: function() { + requestAnimationFrameQueue: [ + ], + + nextTask() { // Spec says: // "Select the oldest task on one of the event loop's task queues" // Which gives browser implementers lots of freedom @@ -50,20 +54,31 @@ This is what the spec says: return null; }, - executeMicrotasks: function() { - if (scriptExecuting) - return; - let microtasks = this.microtaskQueue; - this.microtaskQueue = []; - for (let t of microtasks) - t.execute(); + executeJSCallback(callback) { + callback(); + if (!scriptExecuting) this.executeMicrotasks(); + }, + + executeMicrotasks() { + let microTask; + + while (microtask = this.microtaskQueue.shift()) { + microTask.execute(); + } }, - needsRendering: function() { + executeRequestAnimationFrameCallbacks() { + const callbacks = this.requestAnimationFrameQueue; + this.requestAnimationFrameQueue = []; + + for (const callback of callbacks) this.executeJSCallback(callback); + } + + needsRendering() { return vSyncTime() && (needsDomRerender() || hasEventLoopEventsToDispatch()); }, - render: function() { + render() { dispatchPendingUIEvents(); resizeSteps(); scrollSteps(); @@ -71,7 +86,7 @@ This is what the spec says: cssAnimationSteps(); fullscreenRenderingSteps(); - animationFrameCallbackSteps(); + this.executeRequestAnimationFrameCallbacks(); intersectionObserverSteps(); @@ -93,8 +108,6 @@ This is what the spec says: eventLoop.render(); } - - ## Close reading of the spec Now we understand the spec. From a239c98709e49b3f337a91510b7bf849c3727d45 Mon Sep 17 00:00:00 2001 From: Jake Archibald Date: Tue, 26 Sep 2017 14:43:40 +0100 Subject: [PATCH 2/2] Indenting for syntax highlighting --- README.md | 141 +++++++++++++++++++++++++++--------------------------- 1 file changed, 71 insertions(+), 70 deletions(-) diff --git a/README.md b/README.md index 33c2592..7d2067c 100644 --- a/README.md +++ b/README.md @@ -27,86 +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: [ - ], - - 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); +```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 = []; - needsRendering() { - return vSyncTime() && (needsDomRerender() || hasEventLoopEventsToDispatch()); - }, + for (const callback of callbacks) this.executeJSCallback(callback); + } - render() { - dispatchPendingUIEvents(); - resizeSteps(); - scrollSteps(); - mediaQuerySteps(); - cssAnimationSteps(); - fullscreenRenderingSteps(); + needsRendering() { + return vSyncTime() && (needsDomRerender() || hasEventLoopEventsToDispatch()); + }, - this.executeRequestAnimationFrameCallbacks(); + render() { + dispatchPendingUIEvents(); + resizeSteps(); + scrollSteps(); + mediaQuerySteps(); + cssAnimationSteps(); + fullscreenRenderingSteps(); - intersectionObserverSteps(); + this.executeRequestAnimationFrameCallbacks(); - while (resizeObserverSteps()) { - updateStyle(); - updateLayout(); - } - paint(); + intersectionObserverSteps(); + + while (resizeObserverSteps()) { + updateStyle(); + updateLayout(); } + paint(); } +} - while(true) { - task = eventLoop.nextTask(); - if (task) { - task.execute(); - } - eventLoop.executeMicrotasks(); - if (eventLoop.needsRendering()) - eventLoop.render(); +while(true) { + task = eventLoop.nextTask(); + if (task) { + task.execute(); } + eventLoop.executeMicrotasks(); + if (eventLoop.needsRendering()) + eventLoop.render(); +} +``` ## Close reading of the spec