前言
昨天晚上刷小视频的时候刷到了这个东西,发现挺有意思的,就和大家分享一下这个东西。
为啥会有白屏
我们都知道,现在的网页基本都是SPA单页面应用,也就是说,我们的网页是一次性将所有的资源都加载完毕,然后再进行渲染。这样的话,就会出现一个问题,就是白屏时间过长。因为我们的资源都是一次性加载完毕的,所以我们的白屏时间就会很长。有时候是因为js导致我们的白屏时间过长,今天讲的这个是因为dom导致的白屏时间过长。
白屏效果展示
我写了很简单的一个循环dom代码
1 2 3 4 5 6 7
| <template> <div v-for="n in 300"> <t-row> <t-card :title="`标题${n}`" v-for="j in 100"></t-card> </t-row> </div> </template>
|
我们先来看一下白屏效果,我们先来看一下没有使用defer算法的代码和造成的白屏效果。
添加defer算法
我们在不同的帧率显示不同的dom,帧率越后面的dom越晚显示,这样就可以减少白屏时间了。
hook
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import { onUnmounted, ref, getCurrentInstance } from 'vue';
export function useDefer(maxCount = 100) { const frameCount = ref(0); const instance = getCurrentInstance(); let rafId; function updateFrameCount() { rafId = requestAnimationFrame(() => { frameCount.value++; if (frameCount.value >= maxCount) { cancelAnimationFrame(rafId); return; } updateFrameCount(); }); } updateFrameCount();
onUnmounted(() => { cancelAnimationFrame(rafId); }, instance);
return function defer(n) { return frameCount.value >= n; }; }
|
使用
1 2 3 4 5 6 7 8 9 10 11 12
| <template> <div v-for="n in 300"> <t-row v-if="defer(n)"> <t-card :title="`标题${n}`" v-for="j in 100"></t-card> </t-row> </div> </template> <script setup> import { onMounted } from 'vue'; import {useDefer} from '@/hooks/useDefer'; const defer=useDefer(300); </script>
|
代码讲解
frameCount首先必须要定义为ref,目的就是为了实时渲染,实现dom的双向绑定。我们通过请求动画帧的方式(咱们学3D的对这个可熟悉了)。然后页面即将挂载完成的时候请求动画帧的方法就给关了,超过最大帧数目的时候,也把请求动画帧关了,所以你要确保在使用的时候,你的页面已经挂载完成了,不然就会出现问题。
优化效果
因为太快了,我就从其他页面跳过来给大家看看效果,我么可以看到一下子就出来了,但是仔细看右边的滚动条可以看到它是慢慢在加载元素的
结语
本篇文章就到这里了,更多内容敬请期待,债见~