feat: improve static content stringiciation
Now a single static vnode can contain stringified content for multiple consecutive nodes, which greatly improves the coverage of this optimization.
This commit is contained in:
parent
59d50dad9c
commit
d965bb6227
@ -43,6 +43,7 @@ function walk(
|
|||||||
resultCache: Map<TemplateChildNode, boolean>,
|
resultCache: Map<TemplateChildNode, boolean>,
|
||||||
doNotHoistNode: boolean = false
|
doNotHoistNode: boolean = false
|
||||||
) {
|
) {
|
||||||
|
let hasHoistedNode = false
|
||||||
for (let i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
const child = children[i]
|
const child = children[i]
|
||||||
// only plain elements & text calls are eligible for hoisting.
|
// only plain elements & text calls are eligible for hoisting.
|
||||||
@ -55,6 +56,7 @@ function walk(
|
|||||||
;(child.codegenNode as VNodeCall).patchFlag =
|
;(child.codegenNode as VNodeCall).patchFlag =
|
||||||
PatchFlags.HOISTED + (__DEV__ ? ` /* HOISTED */` : ``)
|
PatchFlags.HOISTED + (__DEV__ ? ` /* HOISTED */` : ``)
|
||||||
child.codegenNode = context.hoist(child.codegenNode!)
|
child.codegenNode = context.hoist(child.codegenNode!)
|
||||||
|
hasHoistedNode = true
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
// node may contain dynamic children, but its props may be eligible for
|
// node may contain dynamic children, but its props may be eligible for
|
||||||
@ -81,6 +83,7 @@ function walk(
|
|||||||
isStaticNode(child.content, resultCache)
|
isStaticNode(child.content, resultCache)
|
||||||
) {
|
) {
|
||||||
child.codegenNode = context.hoist(child.codegenNode)
|
child.codegenNode = context.hoist(child.codegenNode)
|
||||||
|
hasHoistedNode = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// walk further
|
// walk further
|
||||||
@ -98,7 +101,7 @@ function walk(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.transformHoist) {
|
if (hasHoistedNode && context.transformHoist) {
|
||||||
context.transformHoist(children, context)
|
context.transformHoist(children, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,9 +35,29 @@ export const enum StringifyThresholds {
|
|||||||
|
|
||||||
type StringiableNode = PlainElementNode | TextCallNode
|
type StringiableNode = PlainElementNode | TextCallNode
|
||||||
|
|
||||||
// Turn eligible hoisted static trees into stringied static nodes, e.g.
|
/**
|
||||||
// const _hoisted_1 = createStaticVNode(`<div class="foo">bar</div>`)
|
* Turn eligible hoisted static trees into stringied static nodes, e.g.
|
||||||
// This is only performed in non-in-browser compilations.
|
*
|
||||||
|
* ```js
|
||||||
|
* const _hoisted_1 = createStaticVNode(`<div class="foo">bar</div>`)
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* A single static vnode can contain stringified content for **multiple**
|
||||||
|
* consecutive nodes (element and plain text), called a "chunk".
|
||||||
|
* `@vue/runtime-dom` will create the content via innerHTML in a hidden
|
||||||
|
* container element and insert all the nodes in place. The call must also
|
||||||
|
* provide the number of nodes contained in the chunk so that during hydration
|
||||||
|
* we can know how many nodes the static vnode should adopt.
|
||||||
|
*
|
||||||
|
* The optimization scans a children list that contains hoisted nodes, and
|
||||||
|
* tries to find the largest chunk of consecutive hoisted nodes before running
|
||||||
|
* into a non-hoisted node or the end of the list. A chunk is then converted
|
||||||
|
* into a single static vnode and replaces the hoisted expression of the first
|
||||||
|
* node in the chunk. Other nodes in the chunk are considered "merged" and
|
||||||
|
* therefore removed from both the hoist list and the children array.
|
||||||
|
*
|
||||||
|
* This optimization is only performed in Node.js.
|
||||||
|
*/
|
||||||
export const stringifyStatic: HoistTransform = (children, context) => {
|
export const stringifyStatic: HoistTransform = (children, context) => {
|
||||||
let nc = 0 // current node count
|
let nc = 0 // current node count
|
||||||
let ec = 0 // current element with binding count
|
let ec = 0 // current element with binding count
|
||||||
|
Loading…
x
Reference in New Issue
Block a user