Tamplate is parsed by the parse function to generate the AST object. So let’s talk about the Vue mechanism optimization in this chapter, we know that Vue is a static operation with the optimize function, so we’ll skip this node and not compare it to save performance. Let’s start with optimizer.js
export function optimize (root: ? ASTElement, options: CompilerOptions) {
if(! root)return
// staticKeys This is the tag that is considered a static node
isStaticKey = genStaticKeysCached(options.staticKeys || ' ')
isPlatformReservedTag = options.isReservedTag || no
// Mark all static nodes of the AST
markStatic(root)
// The second step marks all the parent nodes of the AST.
markStaticRoots(root, false)}Copy the code
The optimize function markStatic() and markStaticRoots() are the key functions that we’ll look at directly.
function markStatic (node: ASTNode) {
node.static = isStatic(node)
if (node.type === 1) {
// do not make component slot content static. this avoids
// 1. components not able to mutate slot nodes
// 2. static slot content fails for hot-reloading
if(! isPlatformReservedTag(node.tag) && node.tag ! = ='slot' &&
node.attrsMap['inline-template'] = =null
) {
return
}
for (let i = 0, l = node.children.length; i < l; i++) {
const child = node.children[i]
markStatic(child)
if(! child.static) { node.static =false}}if (node.ifConditions) {
for (let i = 1, l = node.ifConditions.length; i < l; i++) {
const block = node.ifConditions[i].block
markStatic(block)
if(! block.static) { node.static =false
}
}
}
}
}
Copy the code
Node. static is assigned to the return value of isStatic, so let’s look at isStatic:
function isStatic (node: ASTNode) :boolean {
if (node.type === 2) { // expression (interpolation)
return false
}
if (node.type === 3) { // text (text)
return true
}
// Handle special characters
return!!!!! (node.pre || ( ! node.hasBindings &&// no dynamic bindings! node.if && ! node.for &&// not v-if or v-for or v-else! isBuiltInTag(node.tag) &&// not a built-in
isPlatformReservedTag(node.tag) && // not a component! isDirectChildOfTemplateFor(node) &&Object.keys(node).every(isStaticKey)
))
}
Copy the code
ASTNode has three types of type: 1 for element node, 2 for interpolation, and 3 for plain text node. When type is 1 or 2, we do not take action. The markStatic function is a recursive static node whose children are marked static by isStatic. The markStaticRoots function marks the ASTElemet tree:
function markStaticRoots (node: ASTNode, isInFor: boolean) {
if (node.type === 1) {
if (node.static || node.once) {
node.staticInFor = isInFor
}
// For a node to qualify as a static root, it should have children that
// are not just static text. Otherwise the cost of hoisting out will
// outweigh the benefits and it's better off to just always render it fresh.
if(node.static && node.children.length && ! ( node.children.length ===1 &&
node.children[0].type === 3
)) {
node.staticRoot = true
return
} else {
node.staticRoot = false
}
if (node.children) {
for (let i = 0, l = node.children.length; i < l; i++) { markStaticRoots(node.children[i], isInFor || !! node.for) } }if (node.ifConditions) {
for (let i = 1, l = node.ifConditions.length; i < l; i++) {
markStaticRoots(node.ifConditions[i].block, isInFor)
}
}
}
}
Copy the code
Here’s an interesting note:
// For a node to qualify as a static root, it should have children that
// are not just static text. Otherwise the cost of hoisting out will
// outweigh the benefits and it's better off to just always render it fresh.
Copy the code
In order for a node to qualify as a static root, its child node should be more than just plain static text, otherwise it would be more expensive and less efficient to tag (extract) it than to render it directly. The optimize function will be faster, higher, and farther than the markup if we have only one plain text inside the root node:
- Walk through the first round, mark
static
Attribute: Judgmentnode
Whether it isstatic
, the tagnode
thechildren
Whether it isstatic
If it does not existstatic
Child node, parent node changed tostatic = false
- Go through the second round, mark
staticRoot
, the tagstatic
The nodes instaticRoot
, mark the nodechildren
thestaticRoot
In order to avoid excessive optimization, onlyStatic text
Nodes whose child nodes are not marked asstaticRoot
.
So the second step optimize is done, we should get to Vue and the core of the step is to mark some static nodes and optimize for the rest of the operation. You’ll wonder why this step is necessary when you know how the diff algorithm works. In the next chapter we will continue to explain the story of compiling AST into render Function Code -Vue source Code parsing series (8) – how to generate the virtual DOM