目录
- 1,背景
- 2,实现
- 2.1,延迟加载的核心代码
- 2.2,模拟的复杂组件
- 2.3. 父组件
- 3,效果
1,背景
当一个页面需要加载较多个组件时,并且组件自身又比较复杂。如果一次性加载,可能等待时间较长,体验不好。
一种解决办法:分批次的来渲染子组件。
2,实现
通过 requestAnimationFrame(callback)
实现,同时能够控制按照指定顺序来渲染。
简单理解为:浏览器会按照一定的频率来重绘页面,大概 60次/s。每次重绘前都会执行 callback
函数。这样的话,我们可以在每次重绘前都只渲染一个组件,来实现组件的延迟加载。
示例代码:
2.1,延迟加载的核心代码
通过 mixin
来实现。大致逻辑:
- 首先会传入一个最大重绘次数。
- 定义一个计数当前重绘次数的变量,每次调用
callback
时自增,重绘次数达到最大则结束requestAnimationFrame
的执行。 - 定义一个方法,参数为指定的顺序,返回值用于判断组件是否展示。
比如v-if="deferItem(5)"
表示浏览器第5次重绘时渲染该组件。
export default function defer(maxFrameCount) {return {data() {return {frameCount: 0,};},mounted() {const refreshFrame = () => {requestAnimationFrame(() => {this.frameCount++;if (this.frameCount < maxFrameCount) {refreshFrame();}});};refreshFrame();},methods: {deferItem(showFrameCount) {return this.frameCount >= showFrameCount;},},};}
2.2,模拟的复杂组件
子组件内部有 20000 个元素需要渲染,来模拟复杂的组件。
<template><div class="container"><div v-for="n in 20000" class="item"></div></div></template><script></script><style scoped>.container {display: flex;flex-wrap: wrap;align-items: center;width: 300px;height: 300px;}.item {width: 5px;height: 5px;background-color: #eee;margin: 0.1em;}</style>
2.3. 父组件
模拟渲染 25 个复杂子组件。
<template><div class="container"><div v-for="n in 25" :key="n" class="wrapper"><HeavyComp v-if="deferItem(n)" /></div></div></template><script>import HeavyComp from "./components/HeavyComp.vue";import defer from "./mixins/defer";export default {components: {HeavyComp,},mixins: [defer(25)],};</script><style scoped>.container {display: flex;flex-wrap: wrap;}.wrapper {border: 1px solid salmon;}</style>
3,效果
requestAnimationFrame 相关解释
以上。