diff --git a/packages/reactivity/src/baseWatch.ts b/packages/reactivity/src/baseWatch.ts index 3f8c19784..84a1b0b1f 100644 --- a/packages/reactivity/src/baseWatch.ts +++ b/packages/reactivity/src/baseWatch.ts @@ -36,9 +36,11 @@ export enum BaseWatchErrorCodes { // TODO move to a scheduler package export interface SchedulerJob extends Function { id?: number + // TODO refactor these boolean flags to a single bitwise flag pre?: boolean active?: boolean computed?: boolean + queued?: boolean /** * Indicates whether the effect is allowed to recursively trigger itself * when managed by the scheduler. diff --git a/packages/runtime-vapor/src/scheduler.ts b/packages/runtime-vapor/src/scheduler.ts index 758e9d30d..c0fea362b 100644 --- a/packages/runtime-vapor/src/scheduler.ts +++ b/packages/runtime-vapor/src/scheduler.ts @@ -28,17 +28,19 @@ const resolvedPromise = /*#__PURE__*/ Promise.resolve() as Promise let currentFlushPromise: Promise | null = null function queueJob(job: SchedulerJob) { - if ( - !queue.length || - !queue.includes( - job, - isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex, - ) - ) { + if (!job.queued) { if (job.id == null) { queue.push(job) } else { - queue.splice(findInsertionIndex(job.id), 0, job) + // fast path when the job id is larger than the tail + if (!job.pre && job.id >= (queue[queue.length - 1]?.id || 0)) { + queue.push(job) + } else { + queue.splice(findInsertionIndex(job.id), 0, job) + } + } + if (!job.allowRecurse) { + job.queued = true } queueFlush() } @@ -46,14 +48,11 @@ function queueJob(job: SchedulerJob) { export function queuePostRenderEffect(cb: SchedulerJobs) { if (!isArray(cb)) { - if ( - !activePostFlushCbs || - !activePostFlushCbs.includes( - cb, - cb.allowRecurse ? postFlushIndex + 1 : postFlushIndex, - ) - ) { + if (!cb.queued) { pendingPostFlushCbs.push(cb) + if (!cb.allowRecurse) { + cb.queued = true + } } } else { // if cb is an array, it is a component lifecycle hook which can only be @@ -93,6 +92,7 @@ function flushPostFlushCbs() { postFlushIndex++ ) { activePostFlushCbs[postFlushIndex]() + activePostFlushCbs[postFlushIndex].queued = false } activePostFlushCbs = null postFlushIndex = 0 @@ -115,6 +115,7 @@ function flushJobs() { try { for (let i = 0; i < queue!.length; i++) { queue![i]() + queue![i].queued = false } } finally { flushIndex = 0