-
Proxy API
- vue2.X 中的 defineProperty API
优点:
- 兼容性好,支持 IE9
缺点:
- Object.definPropecty是对对象属性的监听,要监听这个对象势必要循环+递归,这无疑会有很大的消耗。
- 无法直接监听属性的新增和删除
- 无法直接监听数组(通过hack重写了数组,但也仅能完成7个数组的监听,push()、pop()、shift()、unshift()、splice()、sort()、reverse())
- vue defineProperty 详解 请点击该篇文章查看
- vue3.X中的Proxy API
优点:
- proxy可以直接监听对象而非属性。
- Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,不需要深度遍历监听,性能高于Object.defineProperty。
- 可以直接监听数组的变化。
- Proxy有多达13种拦截⽅法,不限于apply、ownKeys、deleteProperty、has等。
- Proxy作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利
缺点
- Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平。
- vue proxy详解 请点击该篇文章查看
-
生成 Block tree
- Vue.js 2.x
数据更新并触发重新渲染的粒度是组件级的,单个组件内部 需要遍历该组件的整个 vnode 树。
渲染效率的快慢与组件大小成正相关:组件越大,渲染效率越慢。并且,对于一些静态节点,又无数据更新,这些遍历都是性能浪费。
- Vue.js 3.0
通过编译阶段对静态模板的分析,编译生成了 Block tree。
Block tree 是一个将模版基于动态节点指令切割的嵌套区块,每个 区块内部的节点结构是固定的,每个区块只需要追踪自身包含的动态节点。
渲染效率不再与模板大小成正相关,而是与模板中动态节点的数量成正相关。
-
diff算法的提升
diff算法的基础是Virtual DOM,Virtual DOM是一棵以JavaScript对象作为基础的树,每一个节点称为VNode,用对象属性来描述节点,实际上它是一层对真实DOM的抽象,最终可以通过渲染操作使这棵树映射到真实环境上,简单来说Virtual DOM就是一个Js对象,用以描述整个文档。
- Vue2.x 中的虚拟dom是进行全量的对比。
框架通过深度递归遍历新旧两个虚拟DOM树,并比较每个节点上的每个属性,来确定实际DOM的哪些部分需要更新,由于现代JavaScript引擎执行的高级优化,这种有点暴力的算法通常非常快速,但是DOM的更新仍然涉及许多不必要的CPU工作。
- Vue3.0 中新增了静态标记(PatchFlag)
在与上次虚拟结点进行对比的时候,值对比带有patch flag的
节点,并且可以通过flag 的信息得知当前节点要对比的具体内容化。
-
slot 编译优化
- Vue.js 2.x
如果有一个组件传入了slot,那么每次父组件更新的时候,会强制使子组件update,造成性能的浪费。
- Vue.js 3.0
优化了slot的生成,使得非动态slot中属性的更新只会触发子组件的更新。动态slot指的是在slot上面使用v-if,v-for,动态slot名字等会导致slot产生运行时动态变化但是又无法被子组件track的操作。
-
hoistStatic 静态提升
- Vue2.x :
无论元素是否参与更新,每次都会重新创建。
- Vue3.0 :
对不参与更新的元素,只会被创建一次,之后会在每次渲染时候被不停的复用。
-
cacheHandlers(事件侦听器缓存)
默认情况下,如onClick事件会被视为动态绑定,所以每次都会追踪它的变化,但是因为是同一个函数,所以不用追踪变化,直接缓存起来复用即可。
-
模板指令
- 组件上 v-bind.sync 代替 v-model。
- <template v-for>和非v-for节点上key用法已更改。
- 在同一元素上使用的 v-if 和 v-for 优先渲染 v-if。
- v-bind="object"现在排序敏感。
- v-on:event.native修饰符已移除。
- v-for中的ref不再注册ref数组。
- $refs替代$children
- 移除过滤器