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 相关文章推荐
23个Javascript弹出窗口特效整理
Feb 25 Javascript
javascript中强制执行toString()具体实现
Apr 27 Javascript
javascript使用isNaN()函数判断变量是否为数字
Sep 21 Javascript
js 实现菜单上下显示附效果图
Nov 21 Javascript
jQuery移除元素自动解绑事件实现思路及代码
May 31 Javascript
JavaScript中的console.time()函数详细介绍
Dec 29 Javascript
JS实现带有抽屉效果的产品类网站多级导航菜单代码
Sep 15 Javascript
详解JavaScript 中getElementsByName在IE中的注意事项
Feb 21 Javascript
JavaScript箭头(arrow)函数详解
Jun 04 Javascript
关于在mongoose中填充外键的方法详解
Aug 14 Javascript
关于jQuery里prev()的简单操作代码
Oct 27 jQuery
js遍历详解(forEach, map, for, for...in, for...of)
Aug 28 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 采集程序中常用的函数
2009/12/09 PHP
php的list()的一步操作给一组变量进行赋值的使用
2011/05/18 PHP
PHP保存带BOM文件的方法
2015/02/12 PHP
php+jquery+html实现点击不刷新加载更多的实例代码
2016/08/12 PHP
PHP基于redis计数器类定义与用法示例
2018/02/08 PHP
php+mysql+ajax 局部刷新点赞/取消点赞功能(每个账号只点赞一次)
2020/07/24 PHP
10款新鲜出炉的 jQuery 插件(Ajax 插件,有幻灯片、图片画廊、菜单等)
2011/06/08 Javascript
jQuery中html()方法用法实例
2014/12/25 Javascript
ajax如何实现页面局部跳转与结果返回
2015/08/24 Javascript
多功能jQuery树插件zTree实现权限列表简单实例
2016/07/12 Javascript
js实现产品缩略图效果
2017/03/10 Javascript
使用Angular CLI生成 Angular 5项目教程详解
2018/03/18 Javascript
jQuery子选择器与可见性选择器实例分析
2019/06/28 jQuery
vue中的面包屑导航组件实例代码
2019/07/01 Javascript
vue使用原生swiper代码实例
2020/02/05 Javascript
nodejs中的异步编程知识点详解
2021/01/17 NodeJs
Python获取当前路径实现代码
2017/05/08 Python
对Python中9种生成新对象的方法总结
2018/05/23 Python
Python实现爬虫爬取NBA数据功能示例
2018/05/28 Python
Django 中使用流响应处理视频的方法
2018/07/20 Python
Numpy截取指定范围内的数据方法
2018/11/14 Python
Python实现的文轩网爬虫完整示例
2019/05/16 Python
pyecharts在数据可视化中的应用详解
2020/06/08 Python
css3气泡 css3关键帧动画创建的动态通知气泡
2013/02/26 HTML / CSS
澳大利亚女性快速时尚零售商:Ally Fashion
2018/04/25 全球购物
ORACLE十问
2015/04/20 面试题
会计电算一体化个人简历的自我评价
2013/10/15 职场文书
医学院校毕业生自荐信范文
2014/01/01 职场文书
大学生党员自我评价范文
2014/04/09 职场文书
优秀少先队员主要事迹材料
2014/05/28 职场文书
车辆年检委托书范本
2014/10/14 职场文书
安全保证书
2015/01/16 职场文书
学校开除通知书
2015/04/25 职场文书
张思德观后感
2015/06/09 职场文书
严以律己学习心得体会
2016/01/13 职场文书
安装Windows Server 2012 R2企业版操作系统并设置好相关参数
2022/04/29 Servers