1.优化了virtual dom
-
virtual dom的diff策略:
2.x:在运行时会对所有节点生成一个虚拟节点树,当页面数据发生变更好,会遍历判断virtual dom所有节点(包括一些不会变化的节点)有没有发生变化;
3.0:
1.在模板编译时就会进行一些优化来减少运行时的开销,在编译时会对模板进行分析,判断哪些节点时静态不会变化,哪些时动态会随着model发生变化的,运行时数据变更只会去判断这些动态的dom节点;
2.静态属性提取:将组件中所有的静态属性提取出来,比对的时候就可以忽略属性只需要去比对data
3.内联事件函数提取:<Comp @click="count++"/>
,这个组件会生成一个内联函数,2.0中因为count的变化每次都会生成一个不一样的内联函数,导致每次都会重新渲染这个组件;3.0中会把这个内联函数catch起来,每次都是用同一个函数,避免不必要的渲染。 -
virtual dom的生成:
2.x:在生成virtual dom的时候需要判断节点时原生的html元素还是自定义组件,产生了运行时开销;
3.0:在编译阶段,就会判断节点是原生的还是自定义组件,原生的就生成原生的virtual dom生成代码,否则就生成组件的virtual dom生成代码。 -
slots生成:
2.x:当一个slot发生变更的时候,首先需要去更新它的父组件,生成新的slot内容,然后再把更新后的slot内容传递到用到slot的子组件,子组件也更新。
3.0:把所有的slot都跟scope slot一样统一生成一个函数,这个函数传递给子组件,子组件来决定什么时候调用这个函数,当slot变更的时候,只需要去重新比对渲染子组件。
2.数据监听系统
vue2.0:使用ES5的Object.defineProperty的getter、setter实现
vue3.0:基于proxy实现了全语言(属性新增删除,数组长度变化等)支持和更好新能的提升,避免了再初始化时对对象的每个属性进行代理
3.便于tree-shaking的代码结构来减小代码尺寸
tree-shaking的作用是,在代码打包的过程中,对于不必要的代码或者没有使用到的代码不打包到最后的结果中,如下代码,当index.js引用了a.js的fun1函数时,tree-shaking起作用的情况下是不会把fun2打包到最后的bundle结果中的。
在使用webpack构建前端的过程中,第一步会使用babel将JavaScript代码编译成es5,其次在webpack中会
进行tree-shaking识别标记出无需打包的代码,最后uglifyjs在压缩代码的过程中会将第二步tree-shaking标记
的无用代码删除掉,以达到进一步压缩代码尺寸的目的。
//a.js
export function fun1() {}
export function fun2() {}
//index.js
import {fun1} from 'a.js'
fun1()
vue2.0:只有一个vue对象进来,所有的东西都挂载在vue的全局对象上
vue3.0:把代码结构可以和tree-shaking配合起来使用,按需引入
4.更好的多端渲染
vue2.0:比如在小程序中使用vue的时候需要去引用一些第三方的框架,他们本质上时对vue的源码进行了部分重构,以支持对不同端的渲染。而且开发者需要随时关注vue的更新以适配vue可能的更新。
vue3.0:引入了一个Custom Render API,框架开发者只需要从一个平台无关的runtime-core(包含了vue的各种组件,virtual dom的相关算法,但是不包含dom的操作)引入createRenderer来将vue的组件渲染到原生
5.更好的typescript支持
vue2.0:可能需要用到一些第三方的插件,例如vue-property-decorator
,就是依赖vue-class-component来进行class形式的代码编写,并通过装饰器进行类型约束
//class形式
<script lang="ts">
import {Vue, Component} from 'vue-property-decorator';
@Component({})
export default class "组件名" extends Vue{
get ValA(){
return 1;
}
}
</script>
//传统的vue代码
<script lang="es6">
import Vue from 'vue';
export default {
computed: {
ValA: function() {
return 1;
}
}
}
</script>
vue3.0:更好的typescript支持包括原生的Class API和TSX
6.time-slicing
因为框架在浏览器的主线程中运行会进行大量的JavaScript操作,这个时候就会导致主线程被block,主线程的block就会导致浏览器完全没有响应。
如下场景:一个输入框,每次用户的输入都会导致页面上大量的组件被重新渲染,而在每次JavaScript进行dom渲染的过程中都会block主线程,在渲染完成之前就无法继续监听用户的输入。带来的问题就是用户安现按键,并没有任何反应。类似于输入匹配的防抖节流。
vue2.0:没有这个概念
vue3.0:有了对time-slicing的支持,将javasciprt代码的执行切割成每一帧的小块(大约为16ms),每一帧执行结束之后不管JavaScript有没有执行完毕,都会将线程交还给浏览器去相应用户事件,响应之后重新进行javascript计算。
网友评论