深入解读深入解读VUE中的异步渲染的实现中的异步渲染的实现
主要介绍了深入解读VUE中的异步渲染的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具
有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
接下来在本文里一起看看当数据变化时,从源码层面逐步分析一下触发页面的响应动作之后,如何做渲染到页面上,展示到用
户层面的。
同时也会了解在Vue中的异步方法NextTick的源码实现,看一看NextTick方法与浏览器的异步API有何联系。
注意,本文涉及的Vue源码版本为2.6.11。
什么是异步渲染?什么是异步渲染?
这个问题应该先要做一个前提补充,当数据在同步变化的时候,页面订阅的响应操作为什么不会与数据变化完全对应,而是在
所有的数据变化操作做完之后,页面才会得到响应,完成页面渲染。
从一个例子体验一下异步渲染机制。
import Vue from 'Vue'
new Vue({
el: '#app',
template: '<div>{{val}}</div>',
data () { return { val: 'init' } },
mounted () {
this.val = '我是第一次页面渲染' // debugger
this.val = '我是第二次页面渲染'
const st = Date.now()
while(Date.now() - st < 3000) {} }})
上面这一段代码中,在mounted里给val属性进行了两次赋值,如果页面渲染与数据的变化完全同步的话,页面应该是在
mounted里有两次渲染。
而由于Vue内部的渲染机制,实际上页面只会渲染一次,把第一次的赋值所带来的的响应与第二次的赋值所带来的的响应进行
一次合并,将最终的val只做一次页面渲染。
而且页面是在执行所有的同步代码执行完后才能得到渲染,在上述例子里的while阻塞代码之后,页面才会得到渲染,就像在
熟悉的setTimeout里的回调函数的执行一样,这就是的异步渲染。
熟悉React的同学,应该很快能想到多次执行setState函数时,页面render的渲染触发,实际上与上面所说的Vue的异步渲染有
异曲同工之妙。
Vue为什么要异步渲染?为什么要异步渲染?
我们可以从用户和性能两个角度来探讨这个问题。
从用户体验角度,从上面例子里便也可以看出,实际上我们的页面只需要展示第二次的值变化,第一次只是一个中间值,如果
渲染后给用户展示,页面会有闪烁效果,反而会造成不好的用户体验。
从性能角度,例子里最终的需要展示的数据其实就是第二次给val赋的值,如果第一次赋值也需要页面渲染则意味着在第二次
最终的结果渲染之前页面还需要渲染一次无用的渲染,无疑增加了性能的消耗。
对于浏览器来说,在数据变化下,无论是引起的重绘渲染还是重排渲染,都有可能会在性能消耗之下造成低效的页面性能,甚
至造成加载卡顿问题。
异步渲染和熟悉的节流函数最终目的是一致的,将多次数据变化所引起的响应变化收集后合并成一次页面渲染,从而更合理的
利用机器资源,提升性能与用户体验。
Vue中如何实现异步渲染?中如何实现异步渲染?
先总结一下原理,在Vue中异步渲染实际在数据每次变化时,将其所要引起页面变化的部分都放到一个异步API的回调函数
里,直到同步代码执行完之后,异步回调开始执行,最终将同步代码里所有的需要渲染变化的部分合并起来,最终执行一次渲
染操作。
拿上面例子来说,当val第一次赋值时,页面会渲染出对应的文字,但是实际这个渲染变化会暂存,val第二次赋值时,再次暂
存将要引起的变化,这些变化操作会被丢到异步API,Promise.then的回调函数中,等到所有同步代码执行完后,then函数的
回调函数得到执行,然后将遍历存储着数据变化的全局数组,将所有数组里数据确定先后优先级,最终合并成一套需要展示到
页面上的数据,执行页面渲染操作操作。
异步队列执行后,存储页面变化的全局数组得到遍历执行,执行的时候会进行一些筛查操作,将重复操作过的数据进行处理,
实际就是先赋值的丢弃不渲染,最终按照优先级最终组合成一套数据渲染。