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 相关文章推荐
js检测客户端不是firefox则提示下载
Apr 07 Javascript
jQuery验证Checkbox是否选中的代码 推荐
Sep 04 Javascript
自己封装的常用javascript函数分享
Jan 07 Javascript
js实现点击图片将图片地址复制到粘贴板的方法
Feb 16 Javascript
JavaScript操作XML/HTML比较常用的对象属性集锦
Oct 30 Javascript
使用JavaScript获取URL中的参数(两种方法)
Nov 16 Javascript
jQuery实现标签页效果实战(4)
Feb 08 Javascript
ES6新增的math,Number方法
Aug 06 Javascript
jquery操作ul的一些操作笔记整理(干货)
Aug 31 jQuery
JS实现的简单折叠展开动画效果示例
Apr 28 Javascript
vue-router路由懒加载的实现(解决vue项目首次加载慢)
Aug 28 Javascript
vue.js click点击事件获取当前元素对象的操作
Aug 07 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
支持oicq头像的留言簿(二)
2006/10/09 PHP
PHP 基于文件头的文件类型验证类函数
2012/05/01 PHP
PHP中的Iterator迭代对象属性详解
2019/04/12 PHP
JavaScript弹簧振子超简洁版 完全符合能量守恒,胡克定理
2009/10/25 Javascript
jquery获得下拉框值的代码
2011/08/13 Javascript
JS继承--原型链继承和类式继承
2013/04/08 Javascript
更快的异步执行(setTimeout多浏览器)
2014/08/12 Javascript
JS实现为表格动态添加标题的方法
2015/03/31 Javascript
星期几的不同脚本写法(推荐)
2016/06/01 Javascript
js事件冒泡、事件捕获和阻止默认事件详解
2016/08/04 Javascript
codeMirror插件使用讲解
2017/01/16 Javascript
js实现贪吃蛇小游戏(容易理解)
2017/01/22 Javascript
解决Linux无法正常安装与卸载Node.js的方法
2018/01/19 Javascript
Node.js Express安装与使用教程
2018/05/11 Javascript
Vue el-autocomplete远程搜索下拉框并实现自动填充功能(推荐)
2019/10/25 Javascript
Vue时间轴 vue-light-timeline的用法说明
2020/10/29 Javascript
Python数据分析之真实IP请求Pandas详解
2016/11/18 Python
修改默认的pip版本为对应python2.7的方法
2018/11/06 Python
Django 外键的使用方法详解
2019/07/19 Python
Windows 平台做 Python 开发的最佳组合(推荐)
2020/07/27 Python
Perricone MD裴礼康美国官网:抗衰老护肤品
2016/09/26 全球购物
ET Mall东森购物网:东森严选
2017/03/06 全球购物
澳大利亚时尚前卫设计师珠宝在线:Amber Sceats
2017/10/04 全球购物
迪奥官网:Dior.com
2018/12/04 全球购物
巴西电子、家电、智能手机购物网站:Girafa
2019/06/04 全球购物
俄罗斯披萨、寿司和面食送货到家服务:2 Берега
2019/12/15 全球购物
为什么group by 和order by会使查询变慢
2014/05/16 面试题
外贸学院会计专业应届生求职信
2013/11/14 职场文书
学生安全责任书
2014/04/15 职场文书
大学生入党积极分子党校学习思想汇报
2014/10/25 职场文书
老公保证书
2015/01/17 职场文书
乡镇一岗双责责任书
2015/01/29 职场文书
2019年大学生职业生涯规划书
2019/03/25 职场文书
golang json数组拼接的实例
2021/04/28 Golang
SpringBoot整合Mybatis Generator自动生成代码
2021/08/23 Java/Android
python如何将mat文件转为png
2022/07/15 Python