使用帧加载vue组件

背景

首页渲染页面的时候,因为加载的元素特别多,页面会出现白屏

解决方案

使用浏览器的API requestAnimationFrame, 比如每一帧加载一个组件,依次加载所有的组件

举例说明

目录结构

javascript 复制代码
components
   --HeavyComp.vue
APP.vue
useDefer.js

useDefer.js

javascript 复制代码
import { ref } from 'vue';
export function useDefer(speed = 1) {
  const count = ref(0);
  let frame = 0;
  
  function update() {
    frame++;
    if (frame % Math.round(60 / speed) === 0) {
      count.value++;
    }
    requestAnimationFrame(update);
  }
  
  update();
  
  return function (n) {
    return count.value >= n;
  };
}

APP.vue

javascript 复制代码
<script setup>
// import HelloWorld from './components/HelloWorld.vue'
import HeavyComp from './components/HeavyComp.vue';
import { useDefer } from './useDefer.js';
const defer  = useDefer();
</script>

<template>
  <div>
    <a href="https://vite.dev" target="_blank">
      <img src="/vite.svg" class="logo" alt="Vite logo" />
    </a>
    <a href="https://vuejs.org/" target="_blank">
      <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
    </a>
  </div>
   <!-- <div class="container">
    <div v-for="n in 100" :key="n">
      <heavy-comp></heavy-comp>
    </div>
   </div> -->
  <div class="container">
    <div v-for="n in 100" :key="n">
      <heavy-comp v-if="defer(n)"></heavy-comp>
    </div>
  </div>
</template>

<style scoped>
.logo {
  height: 6em;
  padding: 1.5em;
  will-change: filter;
  transition: filter 300ms;
}
.logo:hover {
  filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {
  filter: drop-shadow(0 0 2em #42b883aa);
}
.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 1em;
}
</style>

HeavyComp.vue

javascript 复制代码
<script setup>
import { ref } from 'vue'

defineProps({
  msg: String,
})

const count = ref(50)
</script>

<template>
  <div v-for="i in count" :key="i">
  <p>
    Check out
    <a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
      >create-vue</a
    >, the official Vue + Vite starter
  </p>
  <p>
    Learn more about IDE Support for Vue in the
    <a
      href="https://vuejs.org/guide/scaling-up/tooling.html#ide-support"
      target="_blank"
      >Vue Docs Scaling up Guide</a
    >.
  </p>
   <a href="https://vite.dev" target="_blank">
      <img src="/vite.svg" class="logo" alt="Vite logo" />
    </a>
    <a href="https://vuejs.org/" target="_blank">
      <img src="../assets/vue.svg" class="logo vue" alt="Vue logo" />
    </a>
  </div>
</template>

<style scoped>
.read-the-docs {
  color: #888;
}
</style>

效果展示

组件会一步步加载,公司禁止图片,老弟这里没法贴图。自己运行代码查看吧。