فهرست منبع

perf(compiler-vapor): omit redundant nthChild logical index (#14848)

edison 4 هفته پیش
والد
کامیت
6ef0f108e5

+ 2 - 2
packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap

@@ -269,7 +269,7 @@ const t1 = _template("<div><div></div><!><div></div><!><div><button>", 1)
 export function render(_ctx) {
   const n6 = t1()
   const n5 = _next(_child(n6), 1)
-  const n7 = _nthChild(n6, 3, 3)
+  const n7 = _nthChild(n6, 3)
   const p0 = _next(n7, 4)
   const n4 = _child(p0)
   _setInsertionState(n6, n5, 1)
@@ -307,7 +307,7 @@ export function render(_ctx) {
   const n3 = t0()
   const n0 = _child(n3)
   const n1 = _next(n0, 1)
-  const n2 = _nthChild(n3, 3, 3)
+  const n2 = _nthChild(n3, 3)
   const x0 = _txt(n0)
   _setText(x0, _toDisplayString(_ctx.foo))
   _renderEffect(() => {

+ 21 - 1
packages/compiler-vapor/__tests__/transforms/__snapshots__/logicalIndex.spec.ts.snap

@@ -51,6 +51,26 @@ export function render(_ctx) {
 }"
 `;
 
+exports[`compiler: logicalIndex > child/nthChild/next with logicalIndex > nthChild keeps logicalIndex when it differs from element index 1`] = `
+"import { resolveComponent as _resolveComponent, setInsertionState as _setInsertionState, createComponentWithFallback as _createComponentWithFallback, child as _child, nthChild as _nthChild, createIf as _createIf, template as _template } from 'vue';
+const t0 = _template("<div>", 2)
+const t1 = _template("<div><div></div><span></span><!><div><button>", 1)
+
+export function render(_ctx) {
+  const _component_Comp = _resolveComponent("Comp")
+  const n4 = t1()
+  const n5 = _nthChild(n4, 2, 3)
+  _setInsertionState(n4, 0, 0)
+  const n0 = _createComponentWithFallback(_component_Comp)
+  _setInsertionState(n4, n5, 3)
+  const n1 = _createIf(() => (true), () => {
+    const n3 = t0()
+    return n3
+  }, null, 1, true)
+  return n4
+}"
+`;
+
 exports[`compiler: logicalIndex > child/nthChild/next with logicalIndex > nthChild with logicalIndex 1`] = `
 "import { child as _child, next as _next, setInsertionState as _setInsertionState, createAssetComponent as _createAssetComponent, nthChild as _nthChild, createIf as _createIf, template as _template } from 'vue';
 const t0 = _template("<div>", 2)
@@ -59,7 +79,7 @@ const t1 = _template("<div><div></div><!><div></div><!><div><button>", 1)
 export function render(_ctx) {
   const n5 = t1()
   const n4 = _next(_child(n5), 1)
-  const n6 = _nthChild(n5, 3, 3)
+  const n6 = _nthChild(n5, 3)
   _setInsertionState(n5, n4, 1)
   const n0 = _createAssetComponent("Comp")
   _setInsertionState(n5, n6, 3)

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

@@ -43,7 +43,7 @@ const t0 = _template("<div><div>x</div><div>x</div><div> ", 1)
 
 export function render(_ctx) {
   const n1 = t0()
-  const n0 = _nthChild(n1, 2, 2)
+  const n0 = _nthChild(n1, 2)
   const x0 = _txt(n0)
   _renderEffect(() => _setText(x0, _toDisplayString(_ctx.msg)))
   return n1

+ 21 - 2
packages/compiler-vapor/__tests__/transforms/logicalIndex.spec.ts

@@ -57,8 +57,27 @@ describe('compiler: logicalIndex', () => {
           </div>
         </div>
       `)
-      // nthChild(parent, elementIndex=3, logicalIndex=3) for the anchor
-      expect(code).toContain('_nthChild(n5, 3, 3)')
+      // nthChild(parent, elementIndex=3) for the anchor
+      expect(code).toContain('_nthChild(n5, 3)')
+      expect(code).toMatchSnapshot()
+    })
+
+    test('nthChild keeps logicalIndex when it differs from element index', () => {
+      // <div><Comp /><div /><span /><div v-if="true" /><div><button :disabled="foo" /></div></div>
+      // Comp is prepended and not part of the template, so the v-if append
+      // anchor is elementIndex=2 but logicalIndex=3.
+      const { code } = compileWithTransforms(`
+        <div>
+          <Comp />
+          <div />
+          <span />
+          <div v-if="true" />
+          <div>
+            <button :disabled="foo" />
+          </div>
+        </div>
+      `)
+      expect(code).toMatch(/_nthChild\(n\d+, 2, 3\)/)
       expect(code).toMatchSnapshot()
     })
 

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

@@ -56,7 +56,7 @@ describe('compiler: children transform', () => {
         <div>{{ msg }}</div>
       </div>`,
     )
-    expect(code).contains(`const n0 = _nthChild(n1, 2, 2)`)
+    expect(code).contains(`const n0 = _nthChild(n1, 2)`)
     expect(code).toMatchSnapshot()
   })
 

+ 6 - 2
packages/compiler-vapor/src/generators/template.ts

@@ -110,6 +110,10 @@ export function genChildren(
     const elementIndex = index + offset
     const logicalIndex =
       child.logicalIndex !== undefined ? String(child.logicalIndex) : undefined
+    // nthChild defaults the logical index to the element index at runtime, so
+    // the third argument is only needed when hydration uses a different index.
+    const nthChildLogicalIndex =
+      child.logicalIndex === elementIndex ? undefined : logicalIndex
     // p for "placeholder" variables that are meant for possible reuse by
     // other access paths
     const variable =
@@ -125,7 +129,7 @@ export function genChildren(
             helper('nthChild'),
             from,
             String(elementIndex),
-            logicalIndex,
+            nthChildLogicalIndex,
           ),
         )
       }
@@ -148,7 +152,7 @@ export function genChildren(
             helper('nthChild'),
             from,
             String(elementIndex),
-            logicalIndex,
+            nthChildLogicalIndex,
           )
         }
         pushBlock(...init)