From be42f69597cb952340a9777ea399ef11e51f01aa Mon Sep 17 00:00:00 2001 From: szymon Date: Thu, 23 Sep 2021 15:15:18 +0200 Subject: [PATCH 1/3] feat(schedule): scheduler uses macroTasks when possible --- src/schedule.ts | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/schedule.ts b/src/schedule.ts index 7ea7ea09..11cdcacf 100644 --- a/src/schedule.ts +++ b/src/schedule.ts @@ -1,5 +1,4 @@ import { IFiber, ITask, ITaskCallback } from "./type" -import { options } from "./reconcile" const queue: ITask[] = [] const threshold: number = 1000 / 60 @@ -7,7 +6,7 @@ const transitions = [] let deadline: number = 0 export const startTransition = (cb) => { - transitions.push(cb) && postMessage() + transitions.push(cb) && runTransition() } export const schedule = (callback: any): void => { @@ -15,16 +14,29 @@ export const schedule = (callback: any): void => { startTransition(flush) } -const postMessage = (() => { +const transitionRunnerFactory = (useMicrotasks: boolean) => { const cb = () => transitions.splice(0, 1).forEach((c) => c()) + if (useMicrotasks) { + if (typeof queueMicrotask !== "undefined") { + return () => queueMicrotask(cb) + } + const resolvedPromise = Promise.resolve() + return () => resolvedPromise.then(cb) + } + if (typeof MessageChannel !== "undefined") { const { port1, port2 } = new MessageChannel() port1.onmessage = cb return () => port2.postMessage(null) } return () => setTimeout(cb) -})() +} + +const runTransitionAsTask = transitionRunnerFactory(false) +const runTransitionAsMicroTask = transitionRunnerFactory(true) + +let runTransition = runTransitionAsMicroTask const flush = (): void => { deadline = getTime() + threshold @@ -44,10 +56,10 @@ const flush = (): void => { } export const shouldYield = (): boolean => { - if (options.sync) return false - return ( + const isInputPending = (navigator as any)?.scheduling?.isInputPending() || getTime() >= deadline - ) + runTransition = isInputPending ? runTransitionAsTask : runTransitionAsMicroTask + return isInputPending } export const getTime = () => performance.now() From f0e33596318c854ce7522efad444b1e4cd408e29 Mon Sep 17 00:00:00 2001 From: szymon Date: Thu, 23 Sep 2021 15:20:13 +0200 Subject: [PATCH 2/3] chore(demo): update benchmark and concurrent demos --- demo/src/benchmark.tsx | 2 +- demo/src/concurrent.tsx | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/demo/src/benchmark.tsx b/demo/src/benchmark.tsx index 6471d7db..fb63c788 100644 --- a/demo/src/benchmark.tsx +++ b/demo/src/benchmark.tsx @@ -233,4 +233,4 @@ const Main = () => { ) } -render(
, document.body, { sync: true }) \ No newline at end of file +render(
, document.body) \ No newline at end of file diff --git a/demo/src/concurrent.tsx b/demo/src/concurrent.tsx index 322dd082..7ab9f8c0 100644 --- a/demo/src/concurrent.tsx +++ b/demo/src/concurrent.tsx @@ -1,7 +1,7 @@ // import { h, render, useState, useEffect } from 'fre' // import { h, render } from 'preact' // import {useState, useEffect } from 'preact/hooks' -import { render, useState, useEffect,h, createRoot } from '../../src/index' +import { render, useState, useEffect, h } from '../../src/index' const UPDATE_EVERY = 500 const BLOCK_FOR = 5 @@ -297,5 +297,4 @@ ul.solarsystem li.jupiter { ` document.body.insertBefore(div, app) -// render(, app) -createRoot(document.getElementById('app')).render() +render(, app) From d2b0809ea4dde956e6baa6c96210cd3fd78836a8 Mon Sep 17 00:00:00 2001 From: szymon Date: Thu, 23 Sep 2021 15:22:39 +0200 Subject: [PATCH 3/3] chore(package.json): next minor version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 99166363..55cb5d5d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fre", - "version": "2.3.4", + "version": "2.4.0", "type": "module", "main": "dist/fre.js", "unpkg": "dist/fre.umd.js",