目录

  • 1,背景
  • 2,实现
    • 2.1,延迟加载的核心代码
    • 2.2,模拟的复杂组件
    • 2.3. 父组件
  • 3,效果

1,背景

当一个页面需要加载较多个组件时,并且组件自身又比较复杂。如果一次性加载,可能等待时间较长,体验不好。

一种解决办法:分批次的来渲染子组件。

2,实现

通过 requestAnimationFrame(callback) 实现,同时能够控制按照指定顺序来渲染

简单理解为:浏览器会按照一定的频率来重绘页面,大概 60次/s。每次重绘前都会执行 callback 函数。这样的话,我们可以在每次重绘前都只渲染一个组件,来实现组件的延迟加载。

示例代码:

2.1,延迟加载的核心代码

通过 mixin 来实现。大致逻辑:

  1. 首先会传入一个最大重绘次数。
  2. 定义一个计数当前重绘次数的变量,每次调用 callback 时自增,重绘次数达到最大则结束 requestAnimationFrame 的执行。
  3. 定义一个方法,参数为指定的顺序,返回值用于判断组件是否展示。
    比如 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 相关解释

以上。