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闭包用法实例分析
Jan 23 Javascript
jQuery中$.click()无效问题分析
Jan 29 Javascript
jQuery实现商品活动倒计时
Oct 16 Javascript
javascript原生ajax写法分享
Apr 10 Javascript
jQuery基础的工厂函数以及定时器的经典实例分析
May 20 Javascript
Javascript实现前端简单的路由实例
Sep 11 Javascript
微信小程序 教程之WXML
Oct 18 Javascript
AngularJS 与百度地图的结合实例
Oct 20 Javascript
AngularJS执行流程详解
Feb 17 Javascript
Ajax实现不刷新取最新商品
Mar 01 Javascript
关于vue.extend和vue.component的区别浅析
Aug 16 Javascript
原生JS实现顶部导航栏显示按钮+搜索框功能
Dec 25 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/06/20 PHP
Symfony模板的快捷变量用法实例
2016/03/17 PHP
CI框架AR操作(数组形式)实现插入多条sql数据的方法
2016/05/18 PHP
jQuery 验证插件 Web前端设计模式(asp.net)
2010/10/17 Javascript
Javascript中的delete介绍
2012/09/02 Javascript
利用js实现前台动态添加文本框,后台获取文本框内容(示例代码)
2013/11/25 Javascript
jQuery学习总结之jQuery事件
2014/06/30 Javascript
Node.js入门教程:在windows和Linux上安装配置Node.js图文教程
2014/08/14 Javascript
Javascript 读取操作Sql中的Xml字段
2014/10/09 Javascript
js实现按钮加背景图片常用方法
2014/11/01 Javascript
jQuery 翻页组件yunm.pager.js实现div局部刷新的思路
2016/08/11 Javascript
AngularJS下对数组的对比分析
2016/08/24 Javascript
jQuery学习之DOM节点的插入方法总结
2017/01/22 Javascript
vue 多入口文件搭建 vue多页面搭建的实例讲解
2018/03/12 Javascript
微信小程序实现打卡日历功能
2020/09/21 Javascript
webpack中如何加载静态文件的方法步骤
2019/05/18 Javascript
jQuery实现图片随机切换、抽奖功能(实例代码)
2019/10/23 jQuery
vue 检测用户上传图片宽高的方法
2020/02/06 Javascript
vue 页面跳转的实现方式
2021/01/12 Vue.js
python 文件操作删除某行的实例
2017/09/04 Python
python多进程实现进程间通信实例
2017/11/24 Python
对python制作自己的数据集实例讲解
2018/12/12 Python
Python中文件的写入读取以及附加文字方法
2019/01/23 Python
python Django里CSRF 对应策略详解
2019/08/05 Python
python 实现从高分辨图像上抠取图像块
2020/01/02 Python
浅谈pandas.cut与pandas.qcut的使用方法及区别
2020/03/03 Python
利用Canvas模仿百度贴吧客户端loading小球的方法示例
2017/08/13 HTML / CSS
video.js支持m3u8格式直播的实现示例
2020/05/20 HTML / CSS
草莓网美国官网:Strawberrynet USA
2016/12/11 全球购物
乡下人家教学反思
2014/02/01 职场文书
中班幼儿评语大全
2014/04/30 职场文书
2014年征兵标语
2014/06/20 职场文书
大学生求职信怎么写
2015/03/19 职场文书
拔河比赛队名及霸气口号
2015/12/24 职场文书
手把手教你从零开始react+antd搭建项目
2021/06/03 Javascript
uniapp 微信小程序 自定义tabBar 导航
2022/04/22 Javascript