Vue2 - 延迟加载(requestAnimationFrame实现)+ 效果展示

目录

1,背景

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

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

2,实现

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

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

示例代码:

2.1,延迟加载的核心代码

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

  1. 首先会传入一个最大重绘次数。
  2. 定义一个计数当前重绘次数的变量,每次调用 callback 时自增,重绘次数达到最大则结束 requestAnimationFrame 的执行。
  3. 定义一个方法,参数为指定的顺序,返回值用于判断组件是否展示。
    比如 v-if="deferItem(5)" 表示浏览器第5次重绘时渲染该组件。
js 复制代码
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 个元素需要渲染,来模拟复杂的组件。

html 复制代码
<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 个复杂子组件。

html 复制代码
<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 相关解释

以上。

相关推荐
用户6937175001384几秒前
实测!Gemma 4 成功跑在安卓手机上:离线 AI 助手终于来了
android·前端·人工智能
大阿明1 分钟前
使用vite打包并部署vue项目到nginx
前端·vue.js·nginx
小江的记录本6 分钟前
【Swagger】Swagger系统性知识体系全方位结构化总结
java·前端·后端·python·mysql·spring·docker
用户81135818812012 分钟前
【AJAX-Day2】Promise与回调地狱
前端·ajax
Moshow郑锴13 分钟前
npm国内镜像加速之使用 nrm 工具(灵活切换,适合多环境)
前端·npm·node.js
flytam14 分钟前
Claude Agent SDK 深度入门指南 审核中
前端·人工智能·aigc
你猜猜吧16 分钟前
里程三:DSL总结
前端
JarvanMo16 分钟前
当 Flutter 撞上 3D 性能之墙 —— Fluorite(萤石)
前端
Eagle_Clark16 分钟前
从0到1 Vibe Coding 一个项目的真实感受
前端·人工智能·后端
CodeSheep17 分钟前
兄弟被降职降薪,被猎头挖新公司时承诺45万年薪,结果签合同才发现这45万里有“部分”是股权激励,还得2年后才能兑现
前端·后端·程序员