]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
perf: save
authordaiwei <daiwei521@126.com>
Mon, 8 Sep 2025 14:54:00 +0000 (22:54 +0800)
committerdaiwei <daiwei521@126.com>
Mon, 8 Sep 2025 14:54:00 +0000 (22:54 +0800)
packages/runtime-vapor/src/dom/hydration.ts
packages/runtime-vapor/src/dom/node.ts
packages/runtime-vapor/src/insertionState.ts

index 1b27a2e5fd8e0dba3def1645385e415840e48725..d0509098160c282779928144bc7f2c8f65497b13 100644 (file)
@@ -30,6 +30,7 @@ function performHydration<T>(
     // optimize anchor cache lookup
     ;(Comment.prototype as any).$fe = undefined
     ;(Node.prototype as any).$idx = undefined
+    ;(Node.prototype as any).$auc = undefined
     ;(Node.prototype as any).$children = undefined
     isOptimized = true
   }
@@ -136,27 +137,23 @@ function locateHydrationNodeImpl(): void {
   let node: Node | null
   if (insertionAnchor !== undefined) {
     const hydrationState = getHydrationState(insertionParent!)!
-    const {
-      prevDynamicCount,
-      logicalChildren,
-      appendAnchor,
-      insertionAnchors,
-    } = hydrationState
+    const { prevDynamicCount, logicalChildren, appendAnchor } = hydrationState
     // prepend
     if (insertionAnchor === 0) {
       node = logicalChildren[prevDynamicCount]
     }
     // insert
     else if (insertionAnchor instanceof Node) {
-      const seen =
-        (insertionAnchors && insertionAnchors.get(insertionAnchor)) || 0
-      node = seen
-        ? logicalChildren[(insertionAnchor as ChildItem).$idx + seen]
-        : insertionAnchor
-
-      hydrationState.insertionAnchors = (
-        hydrationState.insertionAnchors || new Map()
-      ).set(insertionAnchor, seen + 1)
+      const usedCount = (insertionAnchor as ChildItem).$auc
+      if (usedCount !== undefined) {
+        node =
+          logicalChildren[(insertionAnchor as ChildItem).$idx + usedCount + 1]
+        ;(insertionAnchor as ChildItem).$auc = usedCount + 1
+      } else {
+        node = insertionAnchor
+        hydrationState.insertionAnchorCount++
+        ;(insertionAnchor as ChildItem).$auc = 0
+      }
     }
     // append
     else {
index a43e8315c6911c5a570315ada5c24b9fb27ddce2..21c94eeff092823687a24ccc79cd894a739d267d 100644 (file)
@@ -72,7 +72,7 @@ export function _nthChild(node: InsertionParent, i: number): Node {
 export function __nthChild(node: Node, i: number): Node {
   const hydrationState = getHydrationState(node as ParentNode)
   if (hydrationState) {
-    const { prevDynamicCount, insertionAnchors, logicalChildren } =
+    const { prevDynamicCount, insertionAnchorCount, logicalChildren } =
       hydrationState
     // prevDynamicCount tracks how many dynamic nodes have been processed
     // so far (prepend/insert/append).
@@ -80,12 +80,11 @@ export function __nthChild(node: Node, i: number): Node {
     // anchor node itself and do NOT consume the next child in `logicalChildren`,
     // yet prevDynamicCount is still incremented. This overcounts the base
     // offset by 1 per unique anchor that has appeared.
-    // insertionAnchors.size equals the number of unique anchors seen, so we
+    // insertionAnchorCount equals the number of unique anchors seen, so we
     // subtract it to neutralize those "first-use doesn't consume" cases:
-    //   base = prevDynamicCount - insertionAnchors.size
+    //   base = prevDynamicCount - insertionAnchorCount
     // Then index from this base: logicalChildren[base + i].
-    const size = insertionAnchors ? insertionAnchors.size : 0
-    return logicalChildren[prevDynamicCount - size + i]
+    return logicalChildren[prevDynamicCount - insertionAnchorCount + i]
   }
   return node.childNodes[i]
 }
@@ -103,12 +102,10 @@ export function _next(node: Node): Node {
 export function __next(node: Node): Node {
   const hydrationState = getHydrationState(node.parentNode!)
   if (hydrationState) {
-    const { logicalChildren, insertionAnchors } = hydrationState
-    const seenCount = (insertionAnchors && insertionAnchors.get(node)) || 0
-    // If node is used as an anchor, the first hydration uses node itself,
-    // but seenCount increases, so here needs -1
-    const insertedNodesCount = seenCount === 0 ? 0 : seenCount - 1
-    return logicalChildren[(node as ChildItem).$idx + insertedNodesCount + 1]
+    const { logicalChildren } = hydrationState
+    return logicalChildren[
+      (node as ChildItem).$idx + ((node as ChildItem).$auc || 0) + 1
+    ]
   }
   return node.nextSibling!
 }
index 3cd21600e50e21d0060fece5b3cb12ce41cc01d2..6d53aeec5023cb1d539ecad3391cdda655456179 100644 (file)
@@ -1,11 +1,11 @@
 import { isHydrating } from './dom/hydration'
-export type ChildItem = ChildNode & { $idx: number }
+export type ChildItem = ChildNode & { $idx: number; $auc?: number }
 export type InsertionParent = ParentNode & { $children?: ChildItem[] }
 
 type HydrationState = {
   logicalChildren: ChildItem[]
   prevDynamicCount: number
-  insertionAnchors: Map<Node, number> | null
+  insertionAnchorCount: number
   appendAnchor: Node | null
 }
 export let insertionParent: InsertionParent | undefined
@@ -77,7 +77,7 @@ function initializeHydrationState(
     hydrationStateCache.set(parent, {
       logicalChildren,
       prevDynamicCount: 0,
-      insertionAnchors: null,
+      insertionAnchorCount: 0,
       appendAnchor: null,
     })
   }