From: daiwei Date: Mon, 8 Sep 2025 14:54:00 +0000 (+0800) Subject: perf: save X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2ca2c5f4f1a4c97412e5f81c3dd9c514fa0669a6;p=thirdparty%2Fvuejs%2Fcore.git perf: save --- diff --git a/packages/runtime-vapor/src/dom/hydration.ts b/packages/runtime-vapor/src/dom/hydration.ts index 1b27a2e5fd..d050909816 100644 --- a/packages/runtime-vapor/src/dom/hydration.ts +++ b/packages/runtime-vapor/src/dom/hydration.ts @@ -30,6 +30,7 @@ function performHydration( // 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 { diff --git a/packages/runtime-vapor/src/dom/node.ts b/packages/runtime-vapor/src/dom/node.ts index a43e8315c6..21c94eeff0 100644 --- a/packages/runtime-vapor/src/dom/node.ts +++ b/packages/runtime-vapor/src/dom/node.ts @@ -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! } diff --git a/packages/runtime-vapor/src/insertionState.ts b/packages/runtime-vapor/src/insertionState.ts index 3cd21600e5..6d53aeec50 100644 --- a/packages/runtime-vapor/src/insertionState.ts +++ b/packages/runtime-vapor/src/insertionState.ts @@ -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 | 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, }) }