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技巧收藏
Apr 07 Javascript
简明json介绍
Sep 28 Javascript
JavaScript基本概念初级讲解论坛贴的学习记录
Feb 22 Javascript
json数据的列循环示例
Sep 06 Javascript
js 本地预览的简单实现方法
Feb 18 Javascript
浅谈javascript中的闭包
May 13 Javascript
全面理解闭包机制
Jul 11 Javascript
Jquery删除css属性的简单方法
Dec 04 Javascript
JavaScript实现打地鼠小游戏
Apr 23 Javascript
详解jenkins自动化部署vue
May 14 Javascript
Vue通过懒加载提升页面响应速度
May 10 Vue.js
关于vue-router-link选择样式设置
Apr 30 Vue.js
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
标准PHP的AES加密算法类
2015/03/12 PHP
Jquery 实现Tab效果 思路是js思路
2010/03/02 Javascript
JS TextArea字符串长度限制代码集合
2012/10/31 Javascript
JS获取页面input控件中所有text控件并追加样式属性
2013/02/25 Javascript
客户端js性能优化小技巧整理
2013/11/05 Javascript
JQuery记住用户名密码实现下次自动登录功能
2015/04/27 Javascript
javascript实现随机读取数组的方法
2015/08/03 Javascript
JS实现Fisheye效果动感放大菜单代码
2015/10/21 Javascript
详解javascript数组去重问题
2015/11/06 Javascript
浅析C/C++,Java,PHP,JavaScript,Json数组、对象赋值时最后一个元素后面是否可以带逗号
2016/03/22 Javascript
JavaScript基础知识点归纳(推荐)
2016/07/09 Javascript
IONIC自定义subheader的最佳解决方案
2016/09/22 Javascript
基于JavaScript实现的希尔排序算法分析
2017/04/14 Javascript
nodejs模块学习之connect解析
2017/07/05 NodeJs
[js高手之路]寄生组合式继承的优势详解
2017/08/28 Javascript
node使用request请求的方法
2019/12/20 Javascript
解决angular 使用原生拖拽页面卡顿及表单控件输入延迟问题
2020/04/21 Javascript
微信h5静默和非静默授权获取用户openId的方法和步骤
2020/06/08 Javascript
python 采集中文乱码问题的完美解决方法
2016/09/27 Python
Python实现删除文件中含“指定内容”的行示例
2017/06/09 Python
python测试mysql写入性能完整实例
2018/01/18 Python
Python后台管理员管理前台会员信息的讲解
2019/01/28 Python
浅谈Python反射 &amp; 单例模式
2019/03/21 Python
python 实现多维数组转向量
2019/11/30 Python
pytorch 实现查看网络中的参数
2020/01/06 Python
Python代码执行时间测量模块timeit用法解析
2020/07/01 Python
Python实现弹球小游戏
2020/08/01 Python
video结合canvas实现视频在线截图功能
2018/06/25 HTML / CSS
Book Depository澳大利亚:世界领先的专业在线书店之一
2018/12/27 全球购物
函授本科毕业自我鉴定
2013/10/09 职场文书
大学毕业后的十年规划
2014/01/07 职场文书
2014年法院工作总结
2014/11/24 职场文书
2015年服务员个人工作总结
2015/05/27 职场文书
python基础之错误和异常处理
2021/10/24 Python
教你如何让spark sql写mysql的时候支持update操作
2022/02/15 MySQL
Win11 22H2 2022怎么更新? 获得Win1122H22022版本升级技巧
2022/09/23 数码科技