什么是懒加载
说起懒加载,想必各位掘友都很了解,是优化前端页面的一种方式,就是能不加载的内容就不加载,首次加载的内容变少,加载速度也就快了,也就提升了用户体验。当用户快要浏览到 或 操作到 未加载的内容再去加载。平时工作中的例子还是很多的。比如:
- 图片懒加载
- 页面懒加载
- 组件懒加载
defineAsyncComponent(() => import(/* webpackChunkName: "songlist" */'../../pages/songlist/SongList.vue'))
适用场景
- 不在首屏展示的图片
- 不在首屏展示的页面
- 多个小页面/组件/图片 拼接成的大页面(往往有滚动条)
以上这些场景都可以使用懒加载的方案,将首页不需要加载的内容懒加载,从而提升首页渲染效率。
如何实现
在这之前,去年曾看过黄轶老师的 手把手带你写一个 Vue3 的自定义指令,这篇文章通过指令的方式实现了图片的懒加载,写的非常好!有需要的掘友可以移步去学习一下。
最近在自己搞个小项目玩玩,其中就需要用到懒加载,因为有太多图片,本来想着使用现成的,但是由于uni
中的图片使用 uni
提供的组件image
代替img
标签,上面的指令不太适用,就自己写了一个。那凭啥说是全网最简单的?黄轶老师的源码大概 200 行,我的 50 行。
别着急喷,代码行数并不能代表啥,没别的意思,实现的方案不一样,当然需要的代码行数不一样,通用性,扩展性这些都不一样,所以我只说的的实现思路简单好理解,并没说我实现的多优雅。
思路
- 实现一个懒加载组件,提供默认插槽(可用于加载组件、图片)
- 组件中控制默认插槽加载,在当前屏幕可见即加载(最简单的就是使用v-if)
- 不加载时渲染与内容等宽等高的容器占位(因此有两个 prop,宽、高)
- 加载完成解除控制
- 有些没有加载,页面就关闭了,在 beforeUnMount 去解除控制。
代码很简单,一看就懂:
LazyLoader.vue
可根据实际情况将 uni 的 view 标签换成 div。
<template>
<slot v-if="load"></slot>
<view v-else ref="box" :style="{ height: h, width: w }">
</view>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { initLazyIntersectionObserver } from '@/utils'
const props = defineProps({
w: {
type: String,
default: '100%'
},
h: {
type: String,
default: '100%'
}
})
const load = ref(false)
const box = ref()
let observer
onMounted(() => {
observer = initLazyIntersectionObserver(entry => {
if (entry.isIntersecting) { // 当内容可见
load.value = true
observer.unobserve(box.value.$el)
observer = null
}
})
observer.observe(box.value.$el) // 观察
})
onBeforeUnmount(() => observer && observer.unobserve(box.value.$el)) // 不观察了
</script>
初始化IntersectionObserver
对不熟悉的可参考MDN_IntersectionObserver
export function initLazyIntersectionObserver(fn) {
const observer = new IntersectionObserver(
entrys => entrys.forEach(entry => fn(entry)),
{
rootMargin: '0px',
threshold: 0,
}
);
return observer;
}
使用
效果
我们可以清晰的看到,随着页面的滚动图片资源在请求。
总结
本文主要简要描述了 懒加载 在前端的作用、适用场景、实现。 看完我的实现,各位是不是觉得很简单?觉得简单的 把 简单 打到评论区🥰。
在使用时需要注意浏览器兼容性哦,网上有IntersectionObserver
的 polyfill
。