From 1b50febfe9da07bd4112f0bb9792077c09c5beb8 Mon Sep 17 00:00:00 2001 From: edison Date: Wed, 12 Feb 2025 16:43:26 +0800 Subject: [PATCH] perf(vapor): use nthChild instead of nextn (#12847) --- .../transformChildren.spec.ts.snap | 17 +++++++++++++++-- .../transforms/transformChildren.spec.ts | 12 ++++++++++++ .../compiler-vapor/src/generators/template.ts | 4 ++-- .../__tests__/dom/template.spec.ts | 15 +++++++++++++-- packages/runtime-vapor/src/dom/node.ts | 11 ++++------- packages/runtime-vapor/src/index.ts | 2 +- 6 files changed, 47 insertions(+), 14 deletions(-) diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap index 373b0795b..215ab9036 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap @@ -1,13 +1,13 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`compiler: children transform > children & sibling references 1`] = ` -"import { child as _child, nextn as _nextn, next as _next, createTextNode as _createTextNode, insert as _insert, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue'; +"import { child as _child, nthChild as _nthChild, next as _next, createTextNode as _createTextNode, insert as _insert, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("

", true) export function render(_ctx) { const n4 = t0() const n0 = _child(n4) - const n3 = _nextn(n0, 2) + const n3 = _nthChild(n4, 2) const n2 = _next(n3) const x0 = _child(n0) const n1 = _createTextNode() @@ -22,6 +22,19 @@ export function render(_ctx) { }" `; +exports[`compiler: children transform > efficient find 1`] = ` +"import { child as _child, nthChild as _nthChild, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue'; +const t0 = _template("
x
x
", true) + +export function render(_ctx) { + const n1 = t0() + const n0 = _nthChild(n1, 2) + const x0 = _child(n0) + _renderEffect(() => _setText(x0, _toDisplayString(_ctx.msg))) + return n1 +}" +`; + exports[`compiler: children transform > efficient traversal 1`] = ` "import { child as _child, next as _next, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
x
", true) diff --git a/packages/compiler-vapor/__tests__/transforms/transformChildren.spec.ts b/packages/compiler-vapor/__tests__/transforms/transformChildren.spec.ts index 39b1da072..152911dcd 100644 --- a/packages/compiler-vapor/__tests__/transforms/transformChildren.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/transformChildren.spec.ts @@ -46,4 +46,16 @@ describe('compiler: children transform', () => { ) expect(code).toMatchSnapshot() }) + + test('efficient find', () => { + const { code } = compileWithElementTransform( + `
+
x
+
x
+
{{ msg }}
+
`, + ) + expect(code).contains(`const n0 = _nthChild(n1, 2)`) + expect(code).toMatchSnapshot() + }) }) diff --git a/packages/compiler-vapor/src/generators/template.ts b/packages/compiler-vapor/src/generators/template.ts index 68d4c20b3..0c27a9192 100644 --- a/packages/compiler-vapor/src/generators/template.ts +++ b/packages/compiler-vapor/src/generators/template.ts @@ -70,7 +70,7 @@ export function genChildren( if (offset === 1) { push(...genCall(helper('next'), prev[0])) } else { - push(...genCall(helper('nextn'), prev[0], String(offset))) + push(...genCall(helper('nthChild'), from, String(offset))) } } else { if (newPath.length === 1 && newPath[0] === 0) { @@ -113,7 +113,7 @@ export function genChildren( if (i === 1) { init = genCall(helper('next'), init) } else if (i > 1) { - init = genCall(helper('nextn'), init, String(i)) + init = genCall(helper('nthChild'), resolvedFrom, String(i)) } } push(...init!) diff --git a/packages/runtime-vapor/__tests__/dom/template.spec.ts b/packages/runtime-vapor/__tests__/dom/template.spec.ts index f34702362..85de30987 100644 --- a/packages/runtime-vapor/__tests__/dom/template.spec.ts +++ b/packages/runtime-vapor/__tests__/dom/template.spec.ts @@ -1,5 +1,5 @@ import { template } from '../../src/dom/template' -import { child, next, nextn } from '../../src/dom/node' +import { child, next, nthChild } from '../../src/dom/node' describe('api: template', () => { test('create element', () => { @@ -18,6 +18,17 @@ describe('api: template', () => { expect(root.$root).toBe(true) }) + test('nthChild', () => { + const t = template('
nested

') + const root = t() + const span = nthChild(root, 0) + const b = nthChild(span, 0) + const p = nthChild(root, 1) + expect(span).toBe(root.firstChild) + expect(b).toBe(root.firstChild!.firstChild) + expect(p).toBe(root.firstChild!.nextSibling) + }) + test('next', () => { const t = template('

') const root = t() @@ -26,7 +37,7 @@ describe('api: template', () => { expect(span).toBe(root.childNodes[0]) expect(b).toBe(root.childNodes[1]) - expect(nextn(span, 2)).toBe(root.childNodes[2]) + expect(nthChild(root, 2)).toBe(root.childNodes[2]) expect(next(b)).toBe(root.childNodes[2]) }) }) diff --git a/packages/runtime-vapor/src/dom/node.ts b/packages/runtime-vapor/src/dom/node.ts index f620acb63..83bc32c57 100644 --- a/packages/runtime-vapor/src/dom/node.ts +++ b/packages/runtime-vapor/src/dom/node.ts @@ -19,14 +19,11 @@ export function child(node: ParentNode): Node { } /*! #__NO_SIDE_EFFECTS__ */ -export function next(node: Node): Node { - return node.nextSibling! +export function nthChild(node: Node, i: number): Node { + return node.childNodes[i] } /*! #__NO_SIDE_EFFECTS__ */ -export function nextn(node: Node, offset: number = 1): Node { - for (let i = 0; i < offset; i++) { - node = node.nextSibling! - } - return node +export function next(node: Node): Node { + return node.nextSibling! } diff --git a/packages/runtime-vapor/src/index.ts b/packages/runtime-vapor/src/index.ts index e4b783916..40a847ba8 100644 --- a/packages/runtime-vapor/src/index.ts +++ b/packages/runtime-vapor/src/index.ts @@ -10,7 +10,7 @@ export { createComponent, createComponentWithFallback } from './component' export { renderEffect } from './renderEffect' export { createSlot } from './componentSlots' export { template } from './dom/template' -export { createTextNode, child, next, nextn } from './dom/node' +export { createTextNode, child, nthChild, next } from './dom/node' export { setText, setHtml,