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 相关文章推荐
Jquery iframe内部出滚动条
Feb 11 Javascript
Jquery 模拟用户点击超链接或者按钮的方法
Oct 25 Javascript
JavaScript中获取样式的原生方法小结
Oct 08 Javascript
用Jquery.load载入页面后样式没了页面混乱的解决方法
Oct 20 Javascript
window.open()实现post传递参数
Mar 12 Javascript
深入浅析react native es6语法
Dec 09 Javascript
js实现tab选项卡切换功能
Jan 13 Javascript
BootStrap组件之进度条的基本用法
Jan 19 Javascript
js使用highlight.js高亮你的代码
Aug 18 Javascript
ES6知识点整理之函数对象参数默认值及其解构应用示例
Apr 17 Javascript
vue实现中部导航栏布局功能
Jul 30 Javascript
Element Popover 弹出框的使用示例
Jul 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实现获取图片颜色值的方法
2014/07/11 PHP
PHP图片库imagemagick安装方法
2014/09/23 PHP
php中base_convert()进制数字转换函数实例
2014/11/20 PHP
ThinkPHP5实现作业管理系统中处理学生未交作业与已交作业信息的方法
2016/11/12 PHP
PHP实现的DES加密解密封装类完整实例
2017/04/29 PHP
Yii2框架中日志的使用方法分析
2017/05/22 PHP
windows下的WAMP环境搭建图文教程(推荐)
2017/07/27 PHP
PHP各种常见经典算法总结【排序、查找、翻转等】
2019/08/05 PHP
gearman中worker常驻后台,导致MySQL server has gone away的解决方法
2020/02/27 PHP
JQUBar 基于JQUERY的柱状图插件
2010/11/23 Javascript
jQuery UI Autocomplete 1.8.16 中文输入修正代码
2012/04/16 Javascript
Jquery动态更改一张位图的src与Attr的使用
2013/07/31 Javascript
Node.js中使用socket创建私聊和公聊聊天室
2015/11/19 Javascript
NodeJs下的测试框架Mocha的简单介绍
2017/02/22 NodeJs
js 概率计算(简单版)
2017/09/12 Javascript
解决Angular4项目部署到服务器上刷新404的问题
2018/08/31 Javascript
vue2.0 可折叠列表 v-for循环展示的实例
2018/09/07 Javascript
jQuery插件实现的日历功能示例【附源码下载】
2018/09/07 jQuery
详解vue几种主动刷新的方法总结
2019/02/19 Javascript
150行Node.js实现的dns代理工具
2019/08/02 Javascript
详解vuex数据传输的两种方式及this.$store undefined的解决办法
2019/08/26 Javascript
小程序登录之支付宝授权的实现示例
2019/12/13 Javascript
如何将Node.js中的回调转换为Promise
2020/11/10 Javascript
Python存取XML的常见方法实例分析
2017/03/21 Python
python连接、操作mongodb数据库的方法实例详解
2019/09/11 Python
使用python脚本自动创建pip.ini配置文件代码实例
2019/09/20 Python
Django xadmin开启搜索功能的实现
2019/11/15 Python
python输入一个水仙花数(三位数) 输出百位十位个位实例
2020/05/03 Python
举例详解CSS3中的Transition
2015/07/15 HTML / CSS
雅诗兰黛加拿大官网:Estee Lauder加拿大
2019/07/31 全球购物
法院实习人员自我鉴定
2013/09/26 职场文书
出国导师推荐信
2014/01/16 职场文书
好的旅游活动方案
2014/08/19 职场文书
2014镇党委班子对照检查材料思想汇报
2014/09/23 职场文书
python 破解加密zip文件的密码
2021/04/22 Python
MySQL令人大跌眼镜的隐式转换
2021/08/23 MySQL