也许这是Vue3最简单的懒加载方案了(适用图片/组件)

6,107 阅读2分钟

什么是懒加载

说起懒加载,想必各位掘友都很了解,是优化前端页面的一种方式,就是能不加载的内容就不加载,首次加载的内容变少,加载速度也就快了,也就提升了用户体验。当用户快要浏览到 或 操作到 未加载的内容再去加载。平时工作中的例子还是很多的。比如:

  • 图片懒加载
  • 页面懒加载
  • 组件懒加载
    defineAsyncComponent(() => import(/* webpackChunkName: "songlist" */'../../pages/songlist/SongList.vue'))
    

适用场景

  • 不在首屏展示的图片
  • 不在首屏展示的页面
  • 多个小页面/组件/图片 拼接成的大页面(往往有滚动条)

以上这些场景都可以使用懒加载的方案,将首页不需要加载的内容懒加载,从而提升首页渲染效率。

如何实现

在这之前,去年曾看过黄轶老师的 手把手带你写一个 Vue3 的自定义指令,这篇文章通过指令的方式实现了图片的懒加载,写的非常好!有需要的掘友可以移步去学习一下。

最近在自己搞个小项目玩玩,其中就需要用到懒加载,因为有太多图片,本来想着使用现成的,但是由于uni 中的图片使用 uni提供的组件image代替img标签,上面的指令不太适用,就自己写了一个。那凭啥说是全网最简单的?黄轶老师的源码大概 200 行,我的 50 行。

别着急喷,代码行数并不能代表啥,没别的意思,实现的方案不一样,当然需要的代码行数不一样,通用性,扩展性这些都不一样,所以我只说的的实现思路简单好理解,并没说我实现的多优雅。

思路

  1. 实现一个懒加载组件,提供默认插槽(可用于加载组件、图片)
  2. 组件中控制默认插槽加载,在当前屏幕可见即加载(最简单的就是使用v-if)
  3. 不加载时渲染与内容等宽等高的容器占位(因此有两个 prop,宽、高)
  4. 加载完成解除控制
  5. 有些没有加载,页面就关闭了,在 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;
}

使用

image.png

效果

我们可以清晰的看到,随着页面的滚动图片资源在请求。 1.gif

总结

本文主要简要描述了 懒加载 在前端的作用、适用场景、实现。 看完我的实现,各位是不是觉得很简单?觉得简单的 把 简单 打到评论区🥰。

在使用时需要注意浏览器兼容性哦,网上有IntersectionObserverpolyfill