perf: optimize scheduler queueJob performance (#138)

This commit is contained in:
Evan You 2024-02-25 11:29:45 +08:00 committed by GitHub
parent 669fec8dad
commit ff943f4ddf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 18 additions and 15 deletions

View File

@ -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.

View File

@ -28,17 +28,19 @@ const resolvedPromise = /*#__PURE__*/ Promise.resolve() as Promise<any>
let currentFlushPromise: Promise<void> | 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