前端性能优化 之 图片懒加载

166 阅读2分钟

电商类网站,图片会非常的多,而如果一上来就加载所有的图片,会导致网页加载很慢 图片懒加载的原理就是把图片的真实路径绑定给一个以data开头的自定义属性data-url即可,页面中的img元素,如果没有src属性,浏览器就不会发出请求去下载图片(没有请求就提高了性能)等图片正式进入到可视区中时,才加载对应的图片,否则不请求图片

那么, 问题来了 如何知道图片进入或者离开了可视区?

传统方法: 滚动监听 获取可视窗口的大小 计算 scrollTop+offsetTop+innerHeight,再判断是否进入可视区,当出现在可视区请求正确的图片地址就好了,这个方法虽然能够实现图片懒加载,但需要自己手动去计算,相对比较麻烦

现在给大家分享一个 利用第三方库实现懒加载的方法

安装

@vueuse/core 函数库,它封装了常见的一些交互逻辑

npm i @vueuse/core
yarn add @vueuse/core

使用

用 useIntersectionObserver(),来实现监听进入可视区域行为

import { useIntersectionObserver } from '@vueuse/core'

// 实时监听这个dom是否在可视区内
 const { stop } = useIntersectionObserver(要监视的dom, ([{ isIntersecting }]) => {
//    // 回调函数: 当 isIntersecting 变化时:从可见->不可见; 不可见->可见
//   isIntersecting: 当前是否可见?
 })

// stop: 停止监听

由于懒加载在多个地方都会用到,所以我们可以封装成自定义指令,使用的时候 只需要把 img src 改成自定义指令即可~

// 自定义指令
import { useIntersectionObserver } from '@vueuse/core'
import { App } from 'vue'
import defaultImg from '@/assets/images/200.png'   //默认加载图片
export default {
  install(app: App) {
    // 全局指令
    // lazy   ====> v-lazy
    app.directive('lazy', {
      // mounted是v3中自定义指令的生命周期,它会被自动调用
      // 它表示的涵义和组件的mounted是一致的
      // el 是dom元素, binding
      mounted(el,binding) {
        // 设置默认图
        el.src = defaultImg
        // console.log('lazy', el, binding.value)

        // 实时监听el是否可见,如果可见,给他的src设置binding.value
        const { stop } = useIntersectionObserver(el, ([{isIntersecting}]) => {
          if(isIntersecting) {
            el.src = binding.value
            // 停止
            stop()
          }
        })
        // el是img标签
        // el.onerror 0级dom事件
        // el.onclick = () =>
        // el.addEventListener('click')
        // el.onerror = () => {
        // }
        el.addEventListener('error', () => {
          // console.log('失败11111')
          // 设置默认图
          el.src = defaultImg
        })
      }
    })
  }
}