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 引起的安全问题
Dec 27 Javascript
jquery蒙版控件实现代码
Dec 08 Javascript
一行代码告别document.getElementById
Jun 01 Javascript
自己写的Javascript计算时间差函数
Oct 28 Javascript
jQuery实现从身份证号中获取出生日期和性别的方法分析
Feb 25 Javascript
浅析Bootstrap组件之面板组件
May 04 Javascript
AngularJS中的指令全面解析(必看)
May 20 Javascript
js获取对象、数组的实际长度,元素实际个数的实现代码
Jun 08 Javascript
学习Angular中作用域需要注意的坑
Aug 17 Javascript
使用canvas进行图像编辑的实例
Aug 29 Javascript
Vue + Vue-router 同名路由切换数据不更新的方法
Nov 20 Javascript
Javascript操作select控件代码实例
Feb 14 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
第十四节 命名空间 [14]
2006/10/09 PHP
第八节--访问方式
2006/11/16 PHP
用PHP实现读取和编写XML DOM代码
2010/04/07 PHP
探讨PHP使用eAccelerator的API开发详解
2013/06/09 PHP
php使用mkdir创建多级目录入门例子
2014/05/10 PHP
原生php实现excel文件读写的方法分析
2018/04/25 PHP
浅谈php常用的7大框架的优缺点
2020/07/20 PHP
如何在Laravel之外使用illuminate组件详解
2020/09/20 PHP
Jquery替换已存在于element上的event的方法
2010/03/09 Javascript
JQuery动态创建DOM、表单元素的实现代码
2011/08/09 Javascript
javascript获取鼠标位置部分的实例代码(兼容IE,FF)
2013/08/05 Javascript
如何将网页表格内容导入excel
2014/02/18 Javascript
jQuery的选择器中的通配符使用介绍
2014/03/20 Javascript
javascript中setTimeout的问题解决方法
2014/05/08 Javascript
jQuery中parents()和parent()的区别分析
2014/10/28 Javascript
jquery实现相册一下滑动两次的方法
2015/02/09 Javascript
jQuery添加和删除输入文本框标签代码
2016/05/20 Javascript
对Js OOP编程 创建对象的一些全面理解
2016/07/26 Javascript
Three.js学习之Lamber材质和Phong材质
2016/08/04 Javascript
根据输入邮箱号跳转到相应登录地址的解决方法
2016/12/13 Javascript
取消Bootstrap的dropdown-menu点击默认关闭事件方法
2018/08/10 Javascript
基于vue循环列表时点击跳转页面的方法
2018/08/31 Javascript
Vue防止白屏添加首屏动画的实例
2019/10/31 Javascript
Vue 中获取当前时间并实时刷新的实现代码
2020/05/12 Javascript
纯JS实现五子棋游戏
2020/05/28 Javascript
[02:32]DOTA2英雄基础教程 祸乱之源
2013/12/23 DOTA
[01:02:48]2018DOTA2亚洲邀请赛小组赛 A组加赛 Newbee vs Liquid
2018/04/03 DOTA
利用Python将数值型特征进行离散化操作的方法
2018/11/06 Python
详解将Python程序(.py)转换为Windows可执行文件(.exe)
2019/07/19 Python
python定时任务 sched模块用法实例
2019/11/04 Python
Python模块future用法原理详解
2020/01/20 Python
python根据完整路径获得盘名/路径名/文件名/文件扩展名的方法
2020/04/22 Python
Selenium自动化测试工具使用方法汇总
2020/06/12 Python
详解pandas映射与数据转换
2021/01/22 Python
纯css3实现鼠标经过图片显示描述的动画效果
2014/09/01 HTML / CSS
固特异美国在线轮胎店:Goodyear Tire
2019/02/23 全球购物