Vue项目性能优化之---自定义指令实现图片懒加载、首屏渲染优化(组件数据懒加载)、vue-lazyload的使用

443 阅读3分钟

“携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第22天,点击查看活动详情

Vue项目性能优化之---自定义指令实现图片懒加载、首屏渲染优化(组件数据懒加载)、vue-lazyload的使用

vue-lazyload实现图片懒加载

1 安装 vue-lazyload

  • npm i vue-lazyload -S

2 在 main.js 中进行引用

  •  import VueLazyload from "vue-lazyload";
     Vue.use(VueLazyload)
    

3 自定义配置插件

  •  Vue.use(VueLazyload,{
         // 设置相应的 loading 图和图片错误显示图
         error: require('@/assets/lazy/error.png'),
         loading: require('@/assets/lazy/loading.gif'),
         attempt: 1, // 尝试加载图片数量
         // try: 2 // 加载图片数量
     })
    

4 使用

  • 单图

    •  <img  v-lazy ='图片地址' :key='图片地址'>
      
  • 多图

    •  <div v-lazy-container="{ selector: 'img' }">
         <img data-src="图片地址">
         <img data-src="图片地址">
         <img data-src="图片地址">
         <img data-src="图片地址">   
       </div>
      
  1. ❗✨注:

    • 背景图片中使用懒加载

      • v-lazy:background-image = '' 要注意图片和盒子大小问题
    • 使用时可以添加一个 key 属性

补充

属性作用默认值类型
preLoad预加载高度比例1.3Number
error图片路径错误时加载图片'data-src'String
loading预加载图片(占位图片)'data-src'String
attempt尝试加载图片数量3Number

自定义指令实现图片懒加载

实现原理:

先储存图片地址 不能先放在src上(放在src上直接发请求了) 当图片进入可视区 将src地址换成存储地址

IntersectionObserver介绍

  • callback

    • 两个回调参数 entries , observer
      • entries

        • 被观察的元素信息对象的数组 [{元素信息},{}],信息中的isIntersecting用来判断进入或离开
      • observer

        • 观察实例
  • options 配置参数

    • root
      • 基于的滚动容器,默认是document
    • rootMargin
      • 容器有没有外边距
    • threshold
      • 交叉的比例
  • 实例提供的两个方法

    • observe(dom)
      • 观察哪个dom
    • unobserve(dom)
      • 停止观察那个dom

实现步骤

  1. app.directive() 传入自定义指令的名称和配置
  1. 当使用指令的DOM创建好后,创建一个观察对象 来观察当前使用指令的元素并开始观察
  1. 当进入可视区后停止观察
  1. 把指令的值设置给 el 的 src 属性 ( binding.value 就是指令的值 )
  1. 处理图片加载失败 error是图片加载失败的事件 加载失败后设置默认图 load是图片加载成功

代码实现

基于vue2.0和 IntersectionObserver封装懒加载指令

 // 图片地址(可通过
 import defaultImg from '@/assets/images/200.png'
 // 定义指令
 const defineDirective = (Vue) => {
     // 1.图片懒加载 v-lazy  指令directive
     Vue.directive('lazy', {
         // 监听使用指令的DOM是否创建好
         // el -->传入的dom   binding  --->传入的图片路径
         inserted(el,binding) {  
             // 2.创建一个观察对象 来观察当前使用指令的元素
             const observe = new IntersectionObserver(([{isIntersecting}]) => {
                 if (isIntersecting) {
                     // 进入可视区
                     // 停止观察
                     observe.unobserve(el)
                     // 3.把指令的值设置给el的src属性  binding.value 就是指令的值
                     // 4.处理图片加载失败  error是图片加载失败的事件  load是图片加载成功
                     el.onerror = () => {
                         // 加载失败 设置默认图
                         el.src = defaultImg
                     }
                     el.src = binding.value
                 }
              }, {
                 threshold:0.01
             })
             // 开启观察
             observe.observe(el)
         },
     })
 }
 export default{
     install(Vue){
         defineDirective(Vue)
     }
 }

基于vue3.0和 IntersectionObserver封装懒加载指令

 import defaultImg from '@/assets/images/200.png'
 // 定义指令
 const defineDirective = (app) => {
     // 1.图片懒加载 v-lazy  指令directive
     // 原理:先储存图片地址 不能先放在src上(放在src上直接发请求了) 当图片进入可视区 将src地址换成存储地址
     app.directive('lazy', {
         // 监听使用指令的DOM是否创建好
         // el -->传入的dom   binding  --->传入的图片路径
         mounted(el,binding) {  
             // 2.创建一个观察对象 来观察当前使用指令的元素
             const observe = new IntersectionObserver(([{isIntersecting}]) => {
                 if (isIntersecting) {
                     // 进入可视区
                     // 停止观察
                     observe.unobserve(el)
                     // 3.把指令的值设置给el的src属性  binding.value 就是指令的值
                     // 4.处理图片加载失败  error是图片加载失败的事件  load是图片加载成功
                     el.onerror = () => {
                         // 加载失败 设置默认图
                         el.src = defaultImg
                     }
                     el.src = binding.value
                 }
              }, {
                 threshold:0.01
             })
             // 开启观察
             observe.observe(el)
         },
     })
 }
 export default {
   install (app) {
     defineDirective(app)
   }
 }

首屏渲染优化(组件数据懒加载)

实现原理:

当模块进入到 可视区 ,再发请求获取数据

@vueuse/core中 useIntersectionObserver的使用

\