feat(compiler): optimize text by merging adjacent nodes

This commit is contained in:
Evan You
2019-09-30 14:51:55 -04:00
parent 7ee07447c5
commit e5e40e1e38
11 changed files with 233 additions and 44 deletions

View File

@@ -1,2 +0,0 @@
// TODO merge adjacent text nodes and expressions into a single expression
// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.

View File

@@ -0,0 +1,48 @@
import { NodeTransform } from '../transform'
import {
NodeTypes,
ChildNode,
TextNode,
InterpolationNode,
CompoundExpressionNode
} from '../ast'
const isText = (node: ChildNode): node is TextNode | InterpolationNode =>
node.type === NodeTypes.INTERPOLATION || node.type === NodeTypes.TEXT
// Merge adjacent text nodes and expressions into a single expression
// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.
export const optimizeText: NodeTransform = node => {
if (node.type === NodeTypes.ROOT || node.type === NodeTypes.ELEMENT) {
// perform the transform on node exit so that all expressions have already
// been processed.
return () => {
const children = node.children
let currentContainer: CompoundExpressionNode | undefined = undefined
for (let i = 0; i < children.length; i++) {
const child = children[i]
if (isText(child)) {
for (let j = i + 1; j < children.length; j++) {
const next = children[j]
if (isText(next)) {
if (!currentContainer) {
currentContainer = children[i] = {
type: NodeTypes.COMPOUND_EXPRESSION,
loc: child.loc,
children: [child]
}
}
// merge adjacent text node into current
currentContainer.children.push(` + `, next)
children.splice(j, 1)
j--
} else {
currentContainer = undefined
break
}
}
}
}
}
}
}

View File

@@ -29,7 +29,7 @@ export const transformIf = createStructuralDirectiveTransform(
})
} else {
// locate the adjacent v-if
const siblings = context.parent.children
const siblings = context.parent!.children
const comments = []
let i = siblings.indexOf(node as any)
while (i-- >= -1) {