内容提要
Vue页面中多个接口异步回调分属不同宏任务,会导致频繁重渲染。优化方法:用Promise.all等所有请求完成后再统一赋值,减少渲染次数;或用v-if先隐藏组件,请求完成后再显示,避免中间渲染,必要时可配骨架屏。
延伸解读
理解Vue的渲染触发机制
Vue通过事件循环的宏任务来批量处理数据变更,同一宏任务内的多次赋值只会触发一次渲染。但异步接口回调属于不同的宏任务,每个回调中的赋值都会独立触发渲染。因此,当页面有多个接口请求时,若在每个then中单独赋值,就会导致频繁重渲染,影响性能。理解这一点是优化渲染次数的前提。
Promise.all合并请求减少渲染
使用Promise.all等待所有请求完成后再统一赋值,可以将多个宏任务中的赋值合并到同一个宏任务中,从而只触发一次渲染。这种方法适用于多个接口之间没有依赖关系、可以并行请求的场景。但需要注意,如果请求写在if else分支中,则无法合并,仍会被拆分成多次任务。
v-if控制渲染时机与骨架屏
通过v-if先隐藏依赖异步数据的组件,待所有请求完成后再显示,可以避免中间状态的渲染。这种方法尤其适用于await顺序请求或分支请求无法合并的情况。但隐藏期间页面可能空白,若渲染时间较长,建议配合骨架屏使用,以提升用户体验。
避免过早优化
Vue和React等框架在重新渲染前会进行diff,最小化DOM操作成本。因此,并非所有多接口页面都需要立即优化。只有当页面确实出现明显卡顿或渲染性能问题时,才需要考虑使用Promise.all或v-if等优化手段。过早优化可能增加代码复杂度,而收益有限。
Q&A
Vue 页面中多个接口异步回调为什么会导致频繁重渲染?
因为每个接口的回调函数运行在独立的宏任务中,Vue 会在每个宏任务结束后触发渲染,导致多次重渲染。
如何用 Promise.all 优化 Vue 中多个接口请求的渲染性能?
使用 Promise.all 等待所有请求完成后再统一赋值,这样只触发一次渲染,减少渲染次数。
使用 await 依次请求接口能减少 Vue 的渲染次数吗?
不能。await 写法本质仍是异步,每个 await 后的赋值会拆分到不同宏任务,依然会触发多次渲染。
v-if 如何帮助减少 Vue 页面渲染次数?
先用 v-if 隐藏需要渲染的组件,等所有请求完成后再显示,这样在请求期间不会渲染该部分,避免中间渲染。
使用 v-if 隐藏组件时需要注意什么?
如果渲染时间过长,需要额外添加骨架屏,避免页面长时间空白。
Vue 渲染优化有必要过早进行吗?
没有必要。Vue 和 React 等框架重新渲染前会先 diff DOM 修改情况,最小化渲染成本,不到特别卡的时候无需过早优化。