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 数值型和字符串型之间的转换
Jul 25 Javascript
jquery tab插件制作实现代码
Jun 22 Javascript
基于jquery的回到页面顶部按钮
Jun 27 Javascript
仿微博字符限制效果实现代码
Apr 20 Javascript
js实现在文本框光标处添加字符的方法介绍
Nov 24 Javascript
自己动手实现jQuery Callbacks完整功能代码详解
Nov 25 Javascript
jQuery实现简单日期格式化功能示例
Sep 19 jQuery
JavaScript实现简单随机点名器
Nov 21 Javascript
JavaScript如何判断input数据类型
Feb 06 Javascript
javascript将16进制的字符串转换为10进制整数hex
Mar 05 Javascript
JS不要再到处使用绝对等于运算符了
Apr 30 Javascript
vue里使用create, mounted调用方法
Apr 26 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+Ajax实现唯一校验实现代码[简单应用]
2011/11/29 PHP
YII视图整合kindeditor扩展的方法
2016/07/13 PHP
Yii2配置Nginx伪静态的方法
2017/05/05 PHP
php7基于递归实现删除空文件夹的方法示例
2017/06/15 PHP
Laravel学习教程之View模块详解
2017/09/18 PHP
Yii框架常见缓存应用实例小结
2019/09/09 PHP
JS代码格式化和语法着色V2
2006/10/14 Javascript
javascript学习笔记(七)利用javascript来创建和存储cookie
2011/04/08 Javascript
JQuery与JS里submit()的区别示例介绍
2014/02/17 Javascript
JS小游戏之极速快跑源码详解
2014/09/25 Javascript
Vue.js组件tree实现省市多级联动
2016/12/02 Javascript
详解vantUI框架在vue项目中的应用踩坑
2018/12/06 Javascript
Vue实现一个图片懒加载插件
2019/03/11 Javascript
angular 实现同步验证器跨字段验证的方法
2019/04/11 Javascript
关于vue-cli 3配置打包优化要点(推荐)
2019/04/22 Javascript
微信小程序--特定区域滚动到顶部时固定的方法
2019/04/28 Javascript
vue history 模式打包部署在域名的二级目录的配置指南
2019/07/02 Javascript
Vue商品控件与购物车联动效果的实例代码
2019/07/21 Javascript
vue 判断两个时间插件结束时间必选大于开始时间的代码
2020/11/04 Javascript
关于vue 项目中浏览器跨域的配置问题
2020/11/10 Javascript
用Python的Django框架完成视频处理任务的教程
2015/04/02 Python
python实现从字典中删除元素的方法
2015/05/04 Python
Python基于PycURL实现POST的方法
2015/07/25 Python
Python中functools模块函数解析
2017/03/12 Python
python实现梯度下降算法
2020/03/24 Python
python 获取页面表格数据存放到csv中的方法
2018/12/26 Python
opencv 获取rtsp流媒体视频的实现方法
2019/08/23 Python
基于Python3.7.1无法导入Numpy的解决方式
2020/03/09 Python
Selenium及python实现滚动操作多种方法
2020/07/21 Python
New delete 与malloc free 的联系与区别
2013/02/04 面试题
什么是ESB?请介绍一下ESB?
2015/05/27 面试题
社团招新策划书
2014/02/04 职场文书
全国法院系统开展党的群众路线教育实践活动综述(全文)
2014/10/25 职场文书
画展邀请函
2015/01/31 职场文书
创业计划书之物流运送
2019/09/17 职场文书
MySql分区类型及创建分区的方法
2022/04/13 MySQL