1.diff方法优化
vue2中虚拟dom通过模板创建虚拟节点(js对象),然后使用虚拟节点跟上一次缓存的虚拟节点进行全量的对比。
vue3在与上次虚拟节点进行对比时候,只对比带有patch flag的节点,并且可以通过flag的信息得知当前节点要对比的具体内容
2.hoistStatic 静态提升
静态节点进行提升,静态span被拿到函数体外面,这样在第一次创建后,后面的节点会复用这个创建方法,免去了重复创建节点,大型应用会受益于这个改动,免去了重复的创建操作,优化运行时候的内存占用。
3.cacheHandlers 事件侦听器缓存 [上面的是不使用,下面的是使用的]
不使用cacheHandlers :onclick是看成一个动态的绑定,因为绑定的函数可能会被改变,例如fn本来是data中返回的,之后如果把它替换掉了,这在实际中需要进行一个更新
使用cacheHandlers : 第一次渲染是自动生成一个内联的函数,在内联函数里面引用当前的fn,然后把内联函数隐藏(cache)起来,后续会从缓存读取同一个函数,因为是同一个函数就没有必要追踪变化,这样就把span变成了静态的,手写的内联函数也会被cache起来,这样就会避免一些没必要的更新.
在组件上使用内联函数会受益于这个改动.
4.ssr渲染
当有大量的静态内容的时候,这些内容会被当做字符串推进一个buffer(存储缓冲器)里面,会通过模板插值嵌入进去,这样会比虚拟dom来渲染快上很多。
当静态内容打到一定量级,会用_createStaticVNode方法在客户端去生成一个静态节点(static node),会被直接innerHTML,就不需要创建对象,然后根据对象渲染。
变化侦测
ES6之前,js是没有提供元编程的能力的,也就是没有提供可以拦截原型方法的能力,vue通过覆盖Array原型的方法,来达到做一些自定义操作的目的,比如说发送变化通知。
vue2中覆盖了Array原型中的7个方法,分别是:push、pop、shift、unshift、splice、sort、reverse,所以当直接通过索引改变数组时,vue是追踪不到变化的。
所以在vue2中实现数据双向绑定,是通过Object.definePropertyd劫持各个属性的getter、setter,在读取数据时触发getter,修改数据时候触发setter。
在getter中收集哪些依赖使用了数据,当setter被触发时候,通知getter中收集的依赖数据变化了。
在vue3中改为用Proxy,但是Proxy只能代理一层,对于深层的无法代理。vue3中利用每次set被拦截之前都会拦截到get操作,所以vue3在get中直接对数据进行reactive,这样就大大减少了递归reactive带来的性能消耗。
与Object.definePropertyd对比优势:
1. 可以直接监听对象而非属性
2. 可以直接监听数组的变化
3. Proxy有多达13种拦截方式,不限于apply、ownKeys、deleteProperty、has等等是 Object.defineProperty不具备的
4. Proxy返回的是一个新对象,可以只操作新的对象达到目的,而Object.defineProperty只能遍历对象属性直接修改
————————————————
原文链接:https://blog.csdn.net/weixin_39364136/article/details/107743534