vue3.0源码速读

3,976 阅读3分钟

最近简单看了下vue3.0的源码,正好记录一下自己的阅读心得,后续有机会,会写逐行分析的系列

Runtime Tree Shaking

相比于2.0,3.0的runtime不再挂载在vue的原型下,这样做一个比较明显的好处连runtime都可以tree shaking,如果有些api我们没有用到的话,我们的runtime就会大大减少,再加上gzip和cdn,美滋滋啊

compiler 重构

好像2.0的paser是基于htmlpaser修改的,3.0的paser写的有点像babel之类的编译器,ast给人的感觉更加语义化,这个当然也有ts的功劳,transform和codegen这两块也借助于更好的ast,可读性跟可维护性感觉更高了,上面提到的runtime shaking,也是在codegen的时候来部分引入api从而达到tree shaking,正如前面说的,没有挂载到原型上

更好的vdom diff

这次在vue 3.0方面的vdom diff,没有采用类似react fiber那样的优化,但是性能也是杠杠的,原因还是有很多地方的,

  1. 内部加入shouldUpdateComponent,这个2.0是没有的,虽然vue可以追踪变化,但是在某些情况下,组件不需要更新,但是组件依旧跑了一次update,这个在3.0会shouldUpdateComponent跑一次结果,但是相比于react的pure component的简单对比,这个方法内部做的事情更多,包括使用patchFlag和props的简单对比等方式来决定是否update
  2. key的diff优化,我们都知道不管是vue和react的启发式算法,都依赖于key,因为可以帮助我们更好的判断是否可以复用节点,3.0的key diff来的更彻底,通过patchFlag,如果patchFlag> 0,可以走vip通道进行diff,如果没有,降级,处理具体情况,进行full diff 还是unmount旧节点或者text节点替换,
  3. blockchildren,2.0有静态节点,这样在一个组件diff的过程中,内部的某些节点可以跳过diff,但是如果在一个动态节点内部也有不变的节点呢,3.0会把一个元素内部的变化的部分塞到blockchildren,这样在一个节点diff的过程中,我们如果发现它有blockchildren,那我们可以只针对blockchildren进行diff,而不需要full diff,2.0无法做到这点是因为2.0对静态节点的判断机制是如果有动态属性,则这个节点及下面节点都不算静态节点

新的变化追踪

这个就不用细谈可以吧,大家都知道现在用proxy替代原来的obj.defineProperty来进行监听,虽然里面还有很多小细节,例如对数组以及set、map之类的追踪,不细说是因为这个都烂大街了,但其中对set、map之类的追踪倒是可以看看,毕竟在里面属于单独划分一个collectionhandler去处理

关于SSR

刚才pull了一下代码,发现ssr部分更新了,好像就是对transform方面,处理掉一些node端没有的api、把事件绑定之类去掉等等,可以简单rendertostring,但是还没有达到2.0ssr那么完善,2.0的ssr分析,可以看我之前写的浅谈Vue SSR中的Bundle

其他

3.0还有很多宝藏我还没来得及挖掘,上面只是简单一些总结,肯定有鄙陋,后面或许还有更新,敬请期待~