]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor(scheduler): remove redundant sorting (#11646)
authorskirtle <65301168+skirtles-code@users.noreply.github.com>
Mon, 19 Aug 2024 02:17:45 +0000 (03:17 +0100)
committerGitHub <noreply@github.com>
Mon, 19 Aug 2024 02:17:45 +0000 (10:17 +0800)
packages/runtime-core/src/scheduler.ts

index bcad996299627064f107e61301bc44642e3d6ea2..256ab202780f4682dad9f1abe7ae6f5d6afe9c75 100644 (file)
@@ -64,13 +64,17 @@ export function nextTick<T = void, R = void>(
   return fn ? p.then(this ? fn.bind(this) : fn) : p
 }
 
-// #2768
-// Use binary-search to find a suitable position in the queue,
-// so that the queue maintains the increasing order of job's id,
-// which can prevent the job from being skipped and also can avoid repeated patching.
+// Use binary-search to find a suitable position in the queue. The queue needs
+// to be sorted in increasing order of the job ids. This ensures that:
+// 1. Components are updated from parent to child. As the parent is always
+//    created before the child it will always have a smaller id.
+// 2. If a component is unmounted during a parent component's update, its update
+//    can be skipped.
+// A pre watcher will have the same id as its component's update job. The
+// watcher should be inserted immediately before the update job. This allows
+// watchers to be skipped if the component is unmounted by the parent update.
 function findInsertionIndex(id: number) {
-  // the start index should be `flushIndex + 1`
-  let start = flushIndex + 1
+  let start = isFlushing ? flushIndex + 1 : 0
   let end = queue.length
 
   while (start < end) {
@@ -208,17 +212,6 @@ export function flushPostFlushCbs(seen?: CountMap): void {
 const getId = (job: SchedulerJob): number =>
   job.id == null ? (job.flags! & SchedulerJobFlags.PRE ? -1 : Infinity) : job.id
 
-const comparator = (a: SchedulerJob, b: SchedulerJob): number => {
-  const diff = getId(a) - getId(b)
-  if (diff === 0) {
-    const isAPre = a.flags! & SchedulerJobFlags.PRE
-    const isBPre = b.flags! & SchedulerJobFlags.PRE
-    if (isAPre && !isBPre) return -1
-    if (isBPre && !isAPre) return 1
-  }
-  return diff
-}
-
 function flushJobs(seen?: CountMap) {
   isFlushPending = false
   isFlushing = true
@@ -226,15 +219,6 @@ function flushJobs(seen?: CountMap) {
     seen = seen || new Map()
   }
 
-  // Sort queue before flush.
-  // This ensures that:
-  // 1. Components are updated from parent to child. (because parent is always
-  //    created before the child so its render effect will have smaller
-  //    priority number)
-  // 2. If a component is unmounted during a parent component's update,
-  //    its update can be skipped.
-  queue.sort(comparator)
-
   // conditional usage of checkRecursiveUpdate must be determined out of
   // try ... catch block since Rollup by default de-optimizes treeshaking
   // inside try-catch. This can leave all warning code unshaked. Although