Skip to content

Commit 1b50feb

Browse files
authored
perf(vapor): use nthChild instead of nextn (#12847)
1 parent 10993af commit 1b50feb

File tree

6 files changed

+47
-14
lines changed

6 files changed

+47
-14
lines changed

packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

33
exports[`compiler: children transform > children & sibling references 1`] = `
4-
"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';
4+
"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';
55
const t0 = _template("<div><p> </p> <!><p> </p></div>", true)
66
77
export function render(_ctx) {
88
const n4 = t0()
99
const n0 = _child(n4)
10-
const n3 = _nextn(n0, 2)
10+
const n3 = _nthChild(n4, 2)
1111
const n2 = _next(n3)
1212
const x0 = _child(n0)
1313
const n1 = _createTextNode()
@@ -22,6 +22,19 @@ export function render(_ctx) {
2222
}"
2323
`;
2424

25+
exports[`compiler: children transform > efficient find 1`] = `
26+
"import { child as _child, nthChild as _nthChild, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
27+
const t0 = _template("<div><div>x</div><div>x</div><div> </div></div>", true)
28+
29+
export function render(_ctx) {
30+
const n1 = t0()
31+
const n0 = _nthChild(n1, 2)
32+
const x0 = _child(n0)
33+
_renderEffect(() => _setText(x0, _toDisplayString(_ctx.msg)))
34+
return n1
35+
}"
36+
`;
37+
2538
exports[`compiler: children transform > efficient traversal 1`] = `
2639
"import { child as _child, next as _next, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
2740
const t0 = _template("<div><div>x</div><div><span> </span></div><div><span> </span></div><div><span> </span></div></div>", true)

packages/compiler-vapor/__tests__/transforms/transformChildren.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,16 @@ describe('compiler: children transform', () => {
4646
)
4747
expect(code).toMatchSnapshot()
4848
})
49+
50+
test('efficient find', () => {
51+
const { code } = compileWithElementTransform(
52+
`<div>
53+
<div>x</div>
54+
<div>x</div>
55+
<div>{{ msg }}</div>
56+
</div>`,
57+
)
58+
expect(code).contains(`const n0 = _nthChild(n1, 2)`)
59+
expect(code).toMatchSnapshot()
60+
})
4961
})

packages/compiler-vapor/src/generators/template.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export function genChildren(
7070
if (offset === 1) {
7171
push(...genCall(helper('next'), prev[0]))
7272
} else {
73-
push(...genCall(helper('nextn'), prev[0], String(offset)))
73+
push(...genCall(helper('nthChild'), from, String(offset)))
7474
}
7575
} else {
7676
if (newPath.length === 1 && newPath[0] === 0) {
@@ -113,7 +113,7 @@ export function genChildren(
113113
if (i === 1) {
114114
init = genCall(helper('next'), init)
115115
} else if (i > 1) {
116-
init = genCall(helper('nextn'), init, String(i))
116+
init = genCall(helper('nthChild'), resolvedFrom, String(i))
117117
}
118118
}
119119
push(...init!)

packages/runtime-vapor/__tests__/dom/template.spec.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { template } from '../../src/dom/template'
2-
import { child, next, nextn } from '../../src/dom/node'
2+
import { child, next, nthChild } from '../../src/dom/node'
33

44
describe('api: template', () => {
55
test('create element', () => {
@@ -18,6 +18,17 @@ describe('api: template', () => {
1818
expect(root.$root).toBe(true)
1919
})
2020

21+
test('nthChild', () => {
22+
const t = template('<div><span><b>nested</b></span><p></p></div>')
23+
const root = t()
24+
const span = nthChild(root, 0)
25+
const b = nthChild(span, 0)
26+
const p = nthChild(root, 1)
27+
expect(span).toBe(root.firstChild)
28+
expect(b).toBe(root.firstChild!.firstChild)
29+
expect(p).toBe(root.firstChild!.nextSibling)
30+
})
31+
2132
test('next', () => {
2233
const t = template('<div><span></span><b></b><p></p></div>')
2334
const root = t()
@@ -26,7 +37,7 @@ describe('api: template', () => {
2637

2738
expect(span).toBe(root.childNodes[0])
2839
expect(b).toBe(root.childNodes[1])
29-
expect(nextn(span, 2)).toBe(root.childNodes[2])
40+
expect(nthChild(root, 2)).toBe(root.childNodes[2])
3041
expect(next(b)).toBe(root.childNodes[2])
3142
})
3243
})

packages/runtime-vapor/src/dom/node.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,11 @@ export function child(node: ParentNode): Node {
1919
}
2020

2121
/*! #__NO_SIDE_EFFECTS__ */
22-
export function next(node: Node): Node {
23-
return node.nextSibling!
22+
export function nthChild(node: Node, i: number): Node {
23+
return node.childNodes[i]
2424
}
2525

2626
/*! #__NO_SIDE_EFFECTS__ */
27-
export function nextn(node: Node, offset: number = 1): Node {
28-
for (let i = 0; i < offset; i++) {
29-
node = node.nextSibling!
30-
}
31-
return node
27+
export function next(node: Node): Node {
28+
return node.nextSibling!
3229
}

packages/runtime-vapor/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export { createComponent, createComponentWithFallback } from './component'
1010
export { renderEffect } from './renderEffect'
1111
export { createSlot } from './componentSlots'
1212
export { template } from './dom/template'
13-
export { createTextNode, child, next, nextn } from './dom/node'
13+
export { createTextNode, child, nthChild, next } from './dom/node'
1414
export {
1515
setText,
1616
setHtml,

0 commit comments

Comments
 (0)