vue 3.0 性能提升点预览

年关将近,业务较忙,基本都是凌晨1-2点下班,早上10点半就上班了,一直没有多余的时间学习,今天周日就抽空来回顾一下 11月24号在杭州 举办vueConf大会的视频,然后总结一下vuejs作者 尤雨溪对vue3.0最新进展的介绍

作者一开始就提到了vue3.0的新特性

  1. 更快
  2. 更小
  3. 更易于维护
  4. 更好的多端渲染支持
  5. 新功能

下面就依次举具体例子介绍:

模板编译和virtual DOM runtime 性能方面的优化

1、思想:编译时的优化来减少运行时的开销;如runtime时diff的静态内容直接在编译时就确定好,这样每次在virtual DOM diff时就直接跳过这一段静态内容

我们知道vue的性能主要是消耗在virtual DOM diff这块,作者也明确指出这一块的优化还有很多空间, 所以3.0版本的virtual DOM是完全重构的,在更多的细节方面下功夫以致于初始渲染/更新提速达100%

// 如下面的模板
<template>
  <comp></comp>
  <div>
    <span></span>
  </div>
</template>

// 编译成渲染函数

render() {
const Comp = resolveComponent('Comp', this)
return crateFragment([
  createComponetVNode(Comp, null, null, 0 /* no children */),
  createElementVNode('div', null, [
    createElementVNode('span', null, null, 0 /* no children */)
  ], 2 /* single vnode child */)
], 8 /* mutiple non-keyed children */)
}

上面的代码说明了经过渲染函数生成的代码里面可以做一些优化

  1. 模板里面有组件,也有原生HTML标签,我们可以在编译时直接做判断,如果它是组件就生成对应的virtual DOM 代码, 如果它是原生HTML标签就直接生成对应的virtual DOM代码,这样就不用每次在运行时去做判断,这就是所谓的component fast path。
  2. 同时在生成的virtual DOM里面的函数调用要尽可能的形状一致,就是说生成的函数参数个数要一致,这样就可以让js引擎去优化,这是比较底层的优化方法。
  3. 同样在代码里面还可以生成一些hint(提示),直接生成一个数字告诉它这个div里面有几个节点,这样就省去了很多运行时成本。

优化slots的生成

<Comp>
  <div>{{hello}}</div>
</Comp>

模板编译后:
render(){
  return h(Comp, null, {
    default: () => [h('div', this.hello)]
  }, 6 /* compiler generated slots */)
}

同样看上面的代码,vue2.x版本的slot每次hello更新都要先更新父组件,然后父组件生成新的slot,这就是关联更新,也就是说为了更新一个hello就触发了两个组件更新。新的solts生成机制里面,所有的slot跟scope slot一样统一生成一个函数,这个函数等于可以说是一个lazy的函数,当你把函数传给子组件的时候,由子组件来决定什么时候调用者函数,当子组件来调用这个函数的时候,就是说这个函数是子组件的依赖而不是父组件的依赖了,当hello变动时,子组件调用这个函数,这样只有子组件重新渲染,这样的话就把父组件和子组件的依赖彻底分开了,这样在整个应用中就可以得到一个组件级别的依赖收集,可以进一步避免不必要的重新渲染,不用你像react那样去操心去手动优化过度重绘这个问题。

静态内容提取

<div class='static'>
  <span>static</span>
</div>

在模板中有许多这种不会变的静态内容,可以在编译时直接缓存起来,每次virtual DOM更新时直接忽略这部分内容,也省去了diff的时间

内联事件函数提取

// 2.x的写法会造成子组件不必要的重渲
<comp @click='count++'></comp>

// 3.0的改进点
<comp @clcik='count++'></comp>
import { getBoundMethod } from 'vue'
function __fn1() {
  this.count++
}
render(){
  return h(comp, {
    onEvent: getBoundMethod(__fn1, this)
  })
}

上面的代码在每次渲染函数执行时都会生成一个新的内敛函数,而导致子组件的不必要更新,所以,目前在用vuejs2.x版本在写代码时尽量绑定具体函数名而不是用内敛的写法。那么3.0的改进点就是把这些内敛函数抽出来在内部维护;所以在3.0你可以放心用内敛写法而不用担心造成不需要的子组件重渲。

基于Proxy的新数据监听系统,全语言特性支持 + 更好的性能

  1. 对象属性的增加 / 删除
  2. 数组 index / length 更改
  3. Map, Set, WeakMap, WeakSet
  4. classes

我们知道2.x的数据监听系统是基于Object.defineproperty()这个方法来进行get 、set拦截处理的,新的数据监听系统将会用Proxy来做。因为Proxy自带lazy特性,不会一开始就把所有定义在data函数中的数据进行绑定监听,它会‘按需’来实现数据监听,当你有大量数据在初始化时,性能会有一个大大的提升,作者实测提升将近一倍。全语言特性支持是指支持数组的index、length的更改也能进行监听从而进行响应式数据绑定,在2.x的版本中,我们在data中定义一个数组list,在模板中去v-for遍历渲染,当我们在操作时去更改list[index]的内容是不会被监听到的,更改list.length也不会被监听到,我们需要通过另外的方法,如Vue.$set(list,index,value)。至于 Map, Set, WeakMap, WeakSet,这些数据类型在2.0中也没有支持,同样在写vue组件时我们一般用export default {} ,以对象的形式去写的,3.0会支持class的写法,像react的组件就是class写法。

所有的这些性能优化加起来就达到了一个效果:速度提升一倍,内存占用减半!

更小

vue的runtime将会变得更小,现在2.x也不大,gzip后20+kb。但是呢,它还可以变得更小!怎么做?没错就是:tree-shaking。3.0的代码组织结构更加便于tree-shaking,让我们没有用到的代码在最后编译的时候把它扔掉。如一些内置组件transition,component,一些指令v-model, v-for, 还有一些内置工具函数 asyncCompenet等,这些都可以做成按需引入!作者介绍在所有这些不相干的代码去掉之后,gzip之后只有10kb+!!!

更易于维护

这点其实说针对vue开发团队而言的,同样对于想要看vue源码的同学也是友好的。首先vue3.0的代码从flow迁移到typescript上了,用typescript完全重写了。我感觉未来用typescript写库或者框架是一种趋势的感觉。所以typescript学起来啊,老铁们。当然这对于用户代码没有任何影响,你以前用es6写vue,也可以继续用,只不过对typescript写vue项目的同学更加友好了。代码重构提现在以下几点:

  1. 内部模块解耦
  2. 编译器重构,插件化设计

更好的多端渲染支持

目前国内的小程序一大堆,这确实给开发者带来很大的不必要学习成本,微信搞一个,支付宝搞一个,然后你百度又来一个快应用啥的。vue3.0将会提供一个custom render API: createRender。 createRender函数更好的支持开发者去用vue语法去写支持多端的代码,让你learn once, write more!

其他

  1. 更好的错误堆栈信息提示
  2. vue hooks 大概率取代mixins
  3. time slicing support,把js代码切成一块块去执行,避免大规模计算导致浏览器长时间处于block状态。这是一个非常好的优化,类似于节流的概念,每一帧只做16-17ms的事情。
  4. ie支持,会有一个专门的版本自动降级为用Object.defineproperty()的get 、set拦截处理的数据,并对一些新的ie不支持的用法做出警告。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容

  • 前几天想学学Vue中怎么编写可复用的组件,提到要对Vue的render函数有所了解。可仔细一想,对于Vue的ren...
    kangaroo_v阅读 116,058评论 13 171
  • 几个重要的概念:需求的价格弹性:需求变化的百分比除以价格变化的百分比;机会成本:是指决策过程中面临多项选择,当中被...
    organnn阅读 222评论 0 1
  • 大家好,我是易效能的陶娅,也是孩子们口中的丫丫老师。上期节目里呢,我跟大家分析了孩子拖拉磨蹭背后的原因,从...
    开心0601阅读 264评论 0 0
  • 《花开的声音》 作者:黑潭白龙朗诵:月儿弯弯 光阴宛若须眉男子 总青睐如花的容颜 停不下追逐的脚步 花蕊仿佛痴情的...
    坚子polaris阅读 237评论 2 7
  • (五)最简单的springMVC后台程序 这一小节,我们会搭建一个最简单的springMVC后台服务程序,初步了解...
    Mark_Du阅读 5,302评论 3 3