首页 >web前端 >前端问答 >vue为什么是异步渲染

vue为什么是异步渲染

青灯夜游
青灯夜游原创
2022-12-21 11:59:022644浏览

原因:可以提升性能。如果不采用异步更新,那么每次更新数据都会对当前组件进行重新渲染;所以为了性能考虑,Vue会在本轮数据更新后,再去异步更新视图,而不是每当有数据更新,就立即更新视图。

vue为什么是异步渲染

本教程操作环境:windows7系统、vue3版,DELL G3电脑。

1、nextTick()的原理及作用

nextTick确保我们所操作的DOM是更新之后的。

(1)应用场景在视图更新之后,基于新的视图进行操作。

  • 在数据变化后执行的某个操作,而这个操作需要使用随数据变化而变化的DOM结构的时候,这个操作就需要放在nextTick()的回调函数中。
  • 如果在created()钩子进行DOM操作,created()中dom还没有渲染,一定要放在nextTick()的回调函数中。
  • Vue采用了数据驱动视图的思想,但是在一些情况下,仍然需要操作DOM。有时候,DOM1的数据发生了变化,而DOM2需要从DOM1中获取数据,那这时就会发现DOM2的视图并没有更新,这时就需要用到了nextTick了。

(2)原理:

  • nextTick 的核心是利用了如 Promise 、MutationObserver、setImmediate、setTimeout的原生 JS 方法来模拟对应的微/宏任务的实现;
  • 本质是为了利用 JS的这些异步回调任务队列实现 Vue 框架中自己的异步回调队列;
  • 本质是对JS执行原理事件循环的一种应用

nextTick 是典型的将底层JS执行原理应用到具体案例中的示例,引入异步更新队列机制的原因∶

如果不采用异步更新,那么每次更新数据都会对当前组件进行重新渲染。所以为了性能考虑,Vue 会在本轮数据更新后,再去异步更新视图。而不是每当有数据更新,就立即更新视图。

  • 为了在数据更新操作之后操作DOM,我们可以在数据变化之后立即使用nextTick(callback)
  • nextTick()将回调延迟到下一个事件循环开始时执行, 这样回调函数会在DOM更新完成后被调用,就可以拿到最新的DOM元素了。 

当你设置 vm.someData = 'new value',DOM 并不会马上更新,而是在异步队列被清除,也就是下一个事件循环开始时执行更新才会进行必要的DOM更新。

(3) vue的降级策略

Vue 在内部对异步队列尝试使用原生的 Promise.then、MutationObserver setImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0) 代替,进行降级处理。降级处理的目的都是将flushCallbacks函数放入微任务或者宏任务队列,等待下一次事件循环时来执行

实际刷新队列是有可能在本次事件循环的微任务中刷新的,也可能是在下一个事件循环中刷新的。这取决于代码当前执行的环境,如若当前执行环境支持promise,那么nextTick内部实际会用Promise去执行,那么队列刷新就会在本次事件循环的微任务中去执行。

优先选择微任务的原因:微任务中更新队列是会比在宏任务中更新少一次UI渲染的

2、为何Vue采用异步渲染

vue是组件级更新组件内有数据变化时,该组件就会更新。例:this.a = 1、this.b=2(同一个watcher)

(1)原因:如果不采用异步更新,那么每次更新数据都会对当前组件进行重新渲染。所以为了性能考虑,Vue 会在本轮数据更新后,再去异步更新视图。而不是每当有数据更新,就立即更新视图。

(2)过程:

  • Vue是异步执行dom更新的,一旦观察到数据变化,Vue就会开启一个队列,然后把在同一个事件循环 (event loop) 中 观察到数据变化的 watcher 推送进这个队列。

  • 如果这个watcher被触发多次,只会被推送到队列一次。这种缓冲行为可以有效的去掉重复数据,避免不必要的计算和Dom操作。

  • 而在下一个事件循环时,Vue会清空队列,并进行必要的DOM更新。

3)源码解析:

  • 数据变化时,通过notify通知watcher进行更新操作;

  • 通过subs[i].update依次调用watcher的update(未更新视图);

  • 将watcher放到队列中,在queueWatcher会根据watcher的id进行去重(多个属性依赖一个watcher),如果队列中没有该watcher就会将该watcher添加到队列中(未更新视图);

  • 通过nextTick异步执行flushSchedulerQueue方法刷新watcher队列(更新视图);

 1.png

【相关推荐:vuejs视频教程web前端开发

以上是vue为什么是异步渲染的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn