Vue3为什么这么快


Posted in Javascript onSeptember 23, 2020

总所周知,程序员追求的就是一个字:快!(当然不是什么都追求快的,有些事情快起来是不行滴)

昨天Vue3.0正式发布了,激动的心,颤抖的手,摸了摸我的头发,嗯~还好。

据说Vue3.0相比Vue2.x在性能上提升了1.2~2倍,为啥他就这么快呢?

vue3.0做了以下事情

  • diff算法优化
  • 静态提升(hoistStatic)
  • 事件侦听器缓存(cacheHandlers)
  • SSR优化(看心情更新)

diff算法优化

Vue2.x的diff算法

vue2.x的diff算法叫做全量比较,顾名思义,就是当数据改变的时候,会从头到尾的进行vDom对比,即使有些内容是永恒固定不变的。

Vue3为什么这么快

Vue3.0的diff算法

vue3.0的diff算法有个叫静态标记(PatchFlag)的小玩意,啥是静态标记呢?
简单点说,就是如果你的内容会变,我会给你一个flag,下次数据更新的时候我直接来对比你,我就不对比那些没有标记的了

Vue3为什么这么快

export function render(_ctx, _cache, $props, $setup, $data, $options) {
 return (_openBlock(), _createBlock("div", null, [
  _createVNode("p", null, "'HelloWorld'"),
  _createVNode("p", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)
                        //上面这个1就是静态标记
 ]))
}

那么肯定有人又会问了,为啥是个1呢?

TEXT = 1 // 动态文本节点
CLASS=1<<1,1 // 2//动态class
STYLE=1<<2,// 4 //动态style
PROPS=1<<3,// 8 //动态属性,但不包含类名和样式
FULLPR0PS=1<<4,// 16 //具有动态key属性,当key改变时,需要进行完整的diff比较。
HYDRATE_ EVENTS = 1 << 5,// 32 //带有监听事件的节点
STABLE FRAGMENT = 1 << 6, // 64 //一个不会改变子节点顺序的fragment
KEYED_ FRAGMENT = 1 << 7, // 128 //带有key属性的fragment 或部分子字节有key
UNKEYED FRAGMENT = 1<< 8, // 256 //子节点没有key 的fragment
NEED PATCH = 1 << 9, // 512 //一个节点只会进行非props比较
DYNAMIC_SLOTS = 1 << 10 // 1024 // 动态slot
HOISTED = -1 // 静态节点
// 指示在diff算法中退出优化模式
BALL = -2

静态提升(hoistStatic)

Vue2.x中无论元素是否参与更新,每次都会重新创建然后渲染
Vue3.0中对不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用即可
还是这段熟悉的代码,开启静态提升前 

export function render(_ctx, _cache, $props, $setup, $data, $options) {
 return (_openBlock(), _createBlock("div", null, [
  _createVNode("p", null, "'HelloWorld'"),
  _createVNode("p", null, "'HelloWorld'"),
  _createVNode("p", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)
 ]))
}

开启静态提升后编译结果 

const _hoisted_1 = /*#__PURE__*/_createVNode("p", null, "'HelloWorld'", -1 /* HOISTED */)
const _hoisted_2 = /*#__PURE__*/_createVNode("p", null, "'HelloWorld'", -1 /* HOISTED */)

export function render(_ctx, _cache, $props, $setup, $data, $options) {
 return (_openBlock(), _createBlock("div", null, [
  _hoisted_1,
  _hoisted_2,
  _createVNode("p", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)
 ]))
}

可以看到开启了静态提升后,直接将那两个内容为helloworld的p标签声明在外面了,直接就拿来用了,这么搞的话那肯定会快啊 

事件侦听器缓存

默认情况下onClick会被视为动态绑定,所以每次都会去追踪它的变化
但是因为是同一个函数,所以没有追踪变化,直接缓存起来复用即可
dom结构

<div>
 <button @click = 'onClick'>点我</button>
</div>

开启事件侦听器缓存之前: 

export const render = /*#__PURE__*/_withId(function render(_ctx, _cache, $props, $setup, $data, $options) {
 return (_openBlock(), _createBlock("div", null, [
  _createVNode("button", { onClick: _ctx.onClick }, "点我", 8 /* PROPS */, ["onClick"])
                       // PROPS=1<<3,// 8 //动态属性,但不包含类名和样式
 ]))
})

这里有一个8,表示着这个节点有了静态标记,有静态标记就会进行diff算法对比差异,所以会浪费时间

开启事件侦听器缓存之后: 

export function render(_ctx, _cache, $props, $setup, $data, $options) {
 return (_openBlock(), _createBlock("div", null, [
  _createVNode("button", {
   onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.onClick(...args)))
  }, "点我")
 ]))
}

可以发现,开启事件侦听器缓存后,没有静态标记了,这就快了好多嘛

到此这篇关于Vue3为什么这么快的文章就介绍到这了,更多相关Vue3 快内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
jQuery 使用个人心得
Feb 26 Javascript
禁止选中文字兼容IE、Chrome、FF等
Sep 04 Javascript
javaScript array(数组)使用字符串作为数组下标的方法
Nov 19 Javascript
Jquery ajaxStart()与ajaxStop()方法(实例讲解)
Dec 18 Javascript
关于Sequelize连接查询时inlude中model和association的区别详解
Feb 27 Javascript
纯JS单页面赛车游戏制作代码分享
Mar 03 Javascript
CodeMirror js代码加亮使用总结
Mar 25 Javascript
JQuery 封装 Ajax 常用方法(推荐)
May 21 jQuery
浅谈AngularJS中$http服务的简单用法
May 15 Javascript
JavaScript寄生组合式继承原理与用法分析
Jan 11 Javascript
vue 中固定导航栏的实例代码
Nov 01 Javascript
QT与javascript交互数据的实现
May 26 Javascript
Angular短信模板校验代码
Sep 23 #Javascript
JavaScript实现单点登录的示例
Sep 23 #Javascript
Vue+Java+Base64实现条码解析的示例
Sep 23 #Javascript
通过实例解析jQ Ajax操作相关原理
Sep 23 #Javascript
js实现三角形粒子运动
Sep 22 #Javascript
js操作两个json数组合并、去重,以及删除某一项元素
Sep 22 #Javascript
js实现删除json中指定的元素
Sep 22 #Javascript
You might like
如何设置mysql允许外网访问
2013/06/04 PHP
php中Session的生成机制、回收机制和存储机制探究
2014/08/19 PHP
PHP callback函数使用方法和注意事项
2015/01/23 PHP
WordPress自定义时间显示格式
2015/03/27 PHP
Laravel中使用Queue的最基本操作教程
2017/12/27 PHP
jquery.post用法示例代码
2014/01/03 Javascript
js点击按钮实现水波纹效果代码(CSS3和Canves)
2016/09/15 Javascript
AngularJS验证信息框架的封装插件用法【w5cValidator扩展插件】
2016/11/03 Javascript
JS实现异步上传压缩图片
2017/04/22 Javascript
浅谈webpack打包生成的bundle.js文件过大的问题
2018/02/22 Javascript
Vue中Quill富文本编辑器的使用教程
2018/09/21 Javascript
VueCli3构建TS项目的方法步骤
2018/11/07 Javascript
vue h5移动端禁止缩放代码
2019/10/28 Javascript
vue data对象重新赋值无效(未更改)的解决方式
2020/07/24 Javascript
[36:37]2014 DOTA2华西杯精英邀请赛5 24 VG VS iG
2014/05/25 DOTA
python使用PyGame播放Midi和Mp3文件的方法
2015/04/24 Python
浅谈Python的文件类型
2016/05/30 Python
Python环境搭建之OpenCV的步骤方法
2017/10/20 Python
Python实现mysql数据库更新表数据接口的功能
2017/11/19 Python
python求解数组中两个字符串的最小距离
2018/09/27 Python
安装2019Pycharm最新版本的教程详解
2019/10/22 Python
tensorflow 实现自定义梯度反向传播代码
2020/02/10 Python
pandas中的ExcelWriter和ExcelFile的实现方法
2020/04/24 Python
pytorch掉坑记录:model.eval的作用说明
2020/06/23 Python
通过代码实例了解Python异常本质
2020/09/16 Python
英国IT硬件供应商,定制游戏PC:Mesh Computers
2019/03/28 全球购物
为什么要用EJB
2014/04/17 面试题
重写子类方法时,抛出异常的书写注意事项
2015/10/17 面试题
总经理岗位职责
2013/11/09 职场文书
团队精神演讲稿
2013/12/31 职场文书
校园安全标语
2014/06/07 职场文书
四风查摆问题自查报告
2014/10/10 职场文书
2014年政风行风自查自纠报告
2014/10/21 职场文书
党员四风问题个人对照检查材料
2014/10/26 职场文书
Vue + iView实现Excel上传功能的完整代码
2021/06/22 Vue.js
Flask response响应的具体使用
2021/07/15 Python