Vue3为什么比Vue2快,带你分析其中的六点

1,178 阅读3分钟

这里首先推荐一个网站给大家,该网站可以对Vue模板进行编译。

vue-next-template-explorer.netlify.app/

点击右上角的Options可以选择不同的编译条件

微信截图_20220307120607.png

本文总结了Vue3比Vue2速度更快的六个点,接下来我们逐个进行分析:

Proxy

Vue3利用Proxy来实现响应式,而Vue2中使用了Object.defineProperty()。

但是Object.defineProperty性能较差,因为对深层对象劫持时需要一次性递归,而Proxy只需要在getter时才对进行对象下一层属性的劫持。

PatchFlag

我们先看看下面节点编译后的样子:

微信截图_20220307114733.png

微信截图_20220307114814.png 我们看到上面不同动态节点的值时不一样的,这样的目的就是为了区分静态节点以及不同类型的动态节点。

我们再来看看vue3中与vue2中diff算法的区别: 微信截图_20220307115017.png

在vue2中,diff算法执行时,不管你是静态节点还是动态节点,都会进行比较。但是vue3的话就只会比较patchflag标记的节点,跳过了静态节点的比较,大大节省了时间。

总结:

  • 编译动态节点时,动态节点做标记。
  • 标记分为不同的类型,如TEXT,PROPS。
  • diff算法时,可以区分静态节点,以及不同类型的动态节点。

HoistStatic

首先我们来看一下代码在关闭HoistStatic时编译后的样子:

微信截图_20220307102851.png

微信截图_20220307102902.png

当我们开启HoistStatic之后:

微信截图_20220307102915.png 对比我们发现,原本定义在函数中的静态节点提升到了外层中,这样一来,当我们再次用到该静态节点的时候我们就可以直接使用而不用再去定义了。

如果我们继续定义多个这样的节点:

微信截图_20220307103645.png 我们发现编译之后所有的span节点都被合并成了一个数组:

微信截图_20220307103723.png

总结:

  • 将静态节点提升到父作用域,缓存起来。

  • 多个相邻的静态节点会被存在一个数组中。

  • 典型的拿空间换时间。

CacheHandler

这是用于缓存事件的优化。

看例子,我们看下面的代码编译后的样子:

微信截图_20220307101510.png

微信截图_20220307101528.png

上面这个是没有开启cacheHandler编译后的代码,现在我们开启cachaHandler再进行编译:

微信截图_20220307101539.png

我们可以看到上述代码编译后多了一行,这是对click事件进行了缓存,如果有该点击事件的缓存,那么直接调用即可。

SSR优化

关闭SRR:

微信截图_20220307110608.png

微信截图_20220307110559.png

开启SSR优化:

微信截图_20220307110621.png 我们可以看到开启SSR之后静态节点不需要创建虚拟dom。

总结:

  • 静态节点直接输出,绕过了vdom。
  • 动态节点还是需要动态渲染。

tree-shaking

编译时,根据不同的情况,引入不同的api,而没有用到的api不会引入。即在打包的时候删除没有用到的代码。

例如如果我们只定义一个静态节点:

微信截图_20220307111334.png 编译时api引入情况:

微信截图_20220307111341.png

当我们在定义一个动态节点的时候:

微信截图_20220307111402.png

编译时api引入情况:

微信截图_20220307111410.png 什么情况下会tree-shaking:

  • 编写的代码没有执行,或不可到达。
  • 代码的执行结果不会用到。
  • 模块导出了,但是没有没其它模块用到。

本文到这里就结束啦!如果有什么不正确的地方,欢迎评论区指正。如果喜欢的话,也请顺便点个赞再走吧~~