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 相关文章推荐
如何在Mozilla Gecko 用Javascript加载XSL
Jan 09 Javascript
用JavaScript事件串连执行多个处理过程的方法
Mar 09 Javascript
File文件控件,选中文件(图片,flash,视频)即立即预览显示
Apr 09 Javascript
js 编程笔记 无名函数
Jun 28 Javascript
javascript错误的认识不用关心内存管理
Dec 15 Javascript
JavaScript实现鼠标滑过处生成气泡的方法
May 16 Javascript
JS实现兼容性好,自动置顶的淘宝悬浮工具栏效果
Sep 18 Javascript
js实现文字闪烁特效的方法
Dec 17 Javascript
bootstrap栅格系统示例代码分享
May 22 Javascript
基于JavaScript的数据结构队列动画实现示例解析
Aug 06 Javascript
Webpack3+React16代码分割的实现
Mar 03 Javascript
html中两种获取标签内的值的方法
Jun 16 jQuery
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
根德YB400的电路分析
2021/03/02 无线电
IIS+PHP+MySQL+Zend配置 (视频教程)
2006/12/13 PHP
PHP静态新闻列表自动生成代码
2007/06/14 PHP
php输出xml必须header的解决方法
2014/10/17 PHP
PHP框架Laravel插件Pagination实现自定义分页
2020/04/22 PHP
js window.onload 加载多个函数的方法
2009/11/02 Javascript
监控 url fragment变化的js代码
2010/04/19 Javascript
基于jquery实现漂亮的动态信息提示效果
2011/08/02 Javascript
上传的js验证(图片/文件的扩展名)
2013/04/25 Javascript
浏览器图片选择预览、旋转、批量上传的JS代码实现
2013/12/04 Javascript
Jquery如何实现点击时高亮显示代码
2014/01/22 Javascript
jQuery使用之设置元素样式用法实例
2015/01/19 Javascript
Javascript控制input输入时间格式的方法
2015/01/28 Javascript
jquery通过closest选择器修改上级元素的方法
2015/03/17 Javascript
JS实现的鼠标跟随代码(卡通手型点击效果)
2015/10/26 Javascript
jQuery中选择器的基础使用教程
2016/05/23 Javascript
bootstrap的3级菜单样式,支持母版页保留打开状态实现方法
2016/11/10 Javascript
angularjs封装$http为factory的方法
2017/05/18 Javascript
vue cli 全面解析
2018/02/28 Javascript
vue.js 图片上传并预览及图片更换功能的实现代码
2018/08/27 Javascript
微信小程序把百度地图坐标转换成腾讯地图坐标过程详解
2019/07/10 Javascript
浅谈vue使用axios的回调函数中this不指向vue实例,为undefined
2020/09/21 Javascript
vue使用vue-quill-editor富文本编辑器且将图片上传到服务器的功能
2021/01/13 Vue.js
python实现的登陆Discuz!论坛通用代码分享
2014/07/11 Python
寻找网站后台地址的python脚本
2014/09/01 Python
深入理解Javascript中的this关键字
2015/03/27 Python
python模块导入的细节详解
2018/12/10 Python
dataframe 按条件替换某一列中的值方法
2019/01/29 Python
Python大数据之网络爬虫的post请求、get请求区别实例分析
2019/11/16 Python
Python  word实现读取及导出代码解析
2020/07/09 Python
伦敦哈德森鞋:Hudson Shoes
2018/02/06 全球购物
工作态度检讨书
2014/02/11 职场文书
代理协议书
2014/04/22 职场文书
Pytorch 使用tensor特定条件判断索引
2021/04/08 Python
CSS3鼠标悬浮过渡缩放效果
2021/04/17 HTML / CSS
Python实现简单的猜单词
2021/06/15 Python