在vue.js模板编译中,优化器的作用就是将解析器解析出来的AST进行进一步处理,找出AST中的静态节点并打上标记,这些静态节点没有使用任何变量,在首次渲染之后,它的状态都不会再发生变化了,每次重新渲染时都不需要为静态节点创建新的虚拟节点,在更新时也可以跳过静态节点的更新流程,不需要重复渲染,提升了性能。
/**
* Goal of the optimizer: walk the generated template AST tree
* and detect sub-trees that are purely static, i.e. parts of
* the DOM that never needs to change.
*
* Once we detect these sub-trees, we can:
*
* 1. Hoist them into constants, so that we no longer need to
* create fresh nodes for them on each re-render;
* 2. Completely skip them in the patching process.
*/
export function optimize (root: ?ASTElement, options: CompilerOptions) {
if (!root) return
isStaticKey = genStaticKeysCached(options.staticKeys || '')
isPlatformReservedTag = options.isReservedTag || no
// first pass: mark all non-static nodes.
//标记静态节点
markStatic(root)
// second pass: mark static roots.
//标记静态根节点
markStaticRoots(root, false)
}
可以看到,在optimize 函数中,主要做了两件事:1.标记静态节点;2.标记静态根节点。
function markStatic (node: ASTNode) {
//判断节点是不是静态节点
node.static = isStatic(node)
//type为1是元素节点
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 (
!isPlatformReserved