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 22 Javascript
使用jquery获取url以及jquery获取url参数的实现方法
May 25 Javascript
JS中如何实现复选框全选功能
Dec 19 Javascript
js实现选项卡内容切换以及折叠和展开效果【推荐】
Jan 08 Javascript
vue快捷键与基础指令详解
Jun 01 Javascript
原生js实现简单的链式操作
Jul 04 Javascript
详谈AngularJs 控制器、数据绑定、作用域
Jul 09 Javascript
BootStrap TreeView使用实例详解
Nov 01 Javascript
webpack-dev-server远程访问配置方法
Feb 22 Javascript
js canvas实现写字动画效果
Nov 30 Javascript
vue路由拦截器和请求拦截器知识点总结
Nov 08 Javascript
js用正则表达式筛选年月日的实例方法
Jan 04 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
memcached 和 mysql 主从环境下php开发代码详解
2010/05/16 PHP
探讨fckeditor在Php中的配置详解
2013/06/08 PHP
PHP+Redis开发的书签案例实战详解
2019/07/09 PHP
js 图片轮播(5张图片)
2008/12/30 Javascript
关于JavaScript的一些看法
2009/05/27 Javascript
javascript 遍历验证所有文本框的值
2009/08/27 Javascript
JQuery为textarea添加maxlength属性并且兼容IE
2013/04/25 Javascript
判断javascript的数据类型(示例代码)
2013/12/11 Javascript
浅析Cookie中的Path与domain
2013/12/18 Javascript
jquery 插件实现多行文本框[textarea]自动高度
2015/03/04 Javascript
JS实现touch 点击滑动轮播实例代码
2017/01/19 Javascript
node.js中cluster的使用教程
2017/06/09 Javascript
详解Vue爬坑之vuex初识
2017/06/14 Javascript
从setTimeout看js函数执行过程
2017/12/19 Javascript
JavaScript类型相关的常用操作总结
2019/02/14 Javascript
使用React手写一个对话框或模态框的方法示例
2019/04/25 Javascript
vue实现路由监听和参数监听
2019/10/29 Javascript
js实现AI五子棋人机大战
2020/05/28 Javascript
Javascript执行流程细节原理解析
2020/05/14 Javascript
[03:22]DOTA2超级联赛专访单车:找到属于自己的英雄
2013/06/08 DOTA
Python最长公共子串算法实例
2015/03/07 Python
Hadoop中的Python框架的使用指南
2015/04/22 Python
python简单读取大文件的方法
2016/07/01 Python
python:print格式化输出到文件的实例
2018/05/14 Python
Python调用C++,通过Pybind11制作Python接口
2018/10/16 Python
Python大数据之从网页上爬取数据的方法详解
2019/11/16 Python
基于python调用psutil模块过程解析
2019/12/20 Python
德国化妆品和天然化妆品网上商店:kosmetikfuchs.de
2017/06/09 全球购物
SOA面试题:如何在SOA中实现松耦合
2013/07/21 面试题
新娘父亲婚礼致辞
2014/01/16 职场文书
2014年高考决心书
2014/03/11 职场文书
优乐美广告词
2014/03/14 职场文书
导游词之徐州云龙湖
2019/11/19 职场文书
MySQL系列之十 MySQL事务隔离实现并发控制
2021/07/02 MySQL
redis中lua脚本使用教程
2021/11/01 Redis
python机器学习创建基于规则聊天机器人过程示例详解
2021/11/02 Python