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 相关文章推荐
项目实践之javascript技巧
Dec 06 Javascript
js点击页面其它地方将某个显示的DIV隐藏
Jul 12 Javascript
JS保留两位小数 四舍五入函数的小例子
Nov 20 Javascript
JS获取html对象的几种方式介绍
Dec 05 Javascript
用js编写的简单的计算器代码程序
Aug 04 Javascript
基于Jquery实现万圣节快乐特效
Nov 01 Javascript
javascript点击按钮实现隐藏显示切换效果
Feb 03 Javascript
jQuery对象与DOM对象转换方法详解
May 10 Javascript
AnglarJs中的上拉加载实现代码
Feb 08 Javascript
js for终止循环 跳出多层循环
Oct 04 Javascript
jquery实现弹窗(系统提示框)效果
Dec 10 jQuery
如何解决vue在ios微信&quot;复制链接&quot;功能问题
Mar 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
php中ob(Output Buffer 输出缓冲)函数使用方法
2007/07/21 PHP
php preg_filter执行一个正则表达式搜索和替换
2012/02/27 PHP
PHP字符串中特殊符号的过滤方法介绍
2014/02/18 PHP
PHP url的pathinfo模式加载不同控制器的简单实现
2016/08/12 PHP
php设计模式之备忘模式分析【星际争霸游戏案例】
2020/03/24 PHP
Colortip基于jquery的信息提示框插件在IE6下面的显示问题修正方法
2010/12/06 Javascript
JavaScript中的property和attribute介绍
2011/12/26 Javascript
实现点击列表弹出列表索引的两种方式
2013/03/08 Javascript
模拟电子签章盖章效果的jQuery插件源码
2013/06/24 Javascript
JS 获取浏览器和屏幕宽高等信息代码
2014/03/31 Javascript
jquery序列化表单去除指定元素示例代码
2014/04/10 Javascript
使用jQuery重置(reset)表单的方法
2014/05/05 Javascript
JavaScript中的getDay()方法使用详解
2015/06/09 Javascript
JavaScript判断表单中多选框checkbox选中个数的方法
2015/08/17 Javascript
javascript实现自动输出文本(打字特效)
2015/08/27 Javascript
深入理解JavaScript中的浮点数
2016/05/18 Javascript
详解Angular开发中的登陆与身份验证
2016/07/27 Javascript
浅谈JS读取DOM对象(标签)的自定义属性
2016/11/21 Javascript
网页中右键功能的实现方法之contextMenu的使用
2017/02/20 Javascript
JavaScript实现设置默认日期范围为最近40天的方法分析
2017/07/12 Javascript
[01:47]2018年度DOTA2最佳教练-完美盛典
2018/12/16 DOTA
[32:07]完美世界DOTA2联赛PWL S3 LBZS vs Rebirth 第一场 12.16
2020/12/17 DOTA
使用python提取html文件中的特定数据的实现代码
2013/03/24 Python
python采用django框架实现支付宝即时到帐接口
2016/05/17 Python
Python with语句上下文管理器两种实现方法分析
2018/02/09 Python
python获取微信小程序手机号并绑定遇到的坑
2018/11/19 Python
pytorch打印网络结构的实例
2019/08/19 Python
美国正宗奢华复古手袋、珠宝及配饰网站:What Goes Around Comes Around
2018/07/21 全球购物
Guess美国官网:美国知名服装品牌
2019/04/08 全球购物
函授大专自我鉴定
2013/11/01 职场文书
表扬信格式
2014/01/12 职场文书
护士在校生自荐信
2014/02/01 职场文书
2015年护士长个人工作总结
2015/04/24 职场文书
2016高三毕业赠言寄语
2015/12/04 职场文书
浅谈Golang 嵌套 interface 的赋值问题
2021/04/29 Golang
Python 一键获取电脑浏览器的账号密码
2022/05/11 Python