Vue3的性能提升

646 阅读1分钟

对比Vue2和React,Vue3的渲染效率简直不要太快。在分析的时候不仅是读懂相关的代码,更要从设计的角度中得到启发。

模板提升、缓存

Vue3的模板引擎会将我们写的模板编译成为一个render函数,而在编译的时候会进行预编译。编译器会发现静态节点,并将节点进行提升。

vue模板

    <div>Hello World</div>
    <div class='user'>{{name}}</div>

经过模板引擎编译后

const _hoisted_1 = _createVNode('div',null,'Hello World')
const _hoisted_2 = {class:'user'}
functoin render(){
// 直接读取_hoisted_1
// _createVNode('div', hoisted_2, name)
//...
}

当组件里面有大量的静态节点,动静比大时

    <div>
        <p>fruit</p>
        <ul>
            <li>apple</li>
            <li>banner</li>
            <li>orange</li>
            <li>watermelon</li>
            <li>pear</li>
        </ul>
        <span>{{else}}</span>
    </div>

编译后

const _hoisted = _createStaticVNode("<p>fruit</p><ul<li>apple</li><li>banner</li><li>orange</li><li>watermelon</li><li>pear</li></ul>")

当节点中存在事件函数时

<button @click='count++'>add</button>

因为事件函数不会在编译时有变更,可以将事件函数进行缓存,

render(ctx, _cache){
    return _createVNode('button',{
    //保证事件函数只生成一次
    onClick: cache[0] || (cache[0] = ($event) => (ctx.count++))
    })
}

block tree

vue2在对比新旧虚拟Dom的时候是将每个节点一一对比是十分浪费性能的。 vue3则是依托于强大的编译器,会在节点上标记为动态节点或静态节点。根节点会生成一个数组记录所有的动态节点。对比的时候直接找到根节点,也就是block节点。在对比的时候只需要循环数组,就会跳过静态节点,直接对比动态节点。

在进行单个节点对比的时候,由于编译器将模板中的动态属性都有标记,比对效率大大的提升。