性能优化之自定义指令实现图片懒加载

1)图片懒加载

是常见的用于在页面滚动时动态加载图片,而不是在页面加载时一次性加载所有图片。性能优化必备提高页面加载速度的手段,特别是在包含大量图片的网站上。

图片懒加载的原理,其实就是,当图片出现在视口内时,进行图片的加载。

市场上也有成熟的第三方库可以帮助我们实现图片懒加载,如 Vue Lazyloadvue3-lazy

不过在这里,我通过自己的理解,使用浏览器 API------Intersection Observer 实现图片懒加载自定义指令

2)看图说话
3)自定义指令(代码中有详解讲解IntersectionObserver用法)
// src/directives/layload/index.js
// 图片加载中时占位
import loadingImg from '../../asset/layload/loadingImg.gif'
// 图片加载错误时占位
import errorImg from '../../asset/layload/errorImg.png'
export default {
  mounted(el, binding) {
    el.src = loadingImg
    // IntersectionObserver 接口提供了一种异步观察目标元素
    // 与其祖先元素或顶级文档视口(viewport)交叉状态的方法。
    el.Intersection = new IntersectionObserver((entries) => {
      // 如果交叉,则背景图片替换成绑定图片
      if (entries[0].isIntersecting) {
        el.src = binding.value.src
        // 加载成功
        el.onload = (res) => {
          console.log('加载成功', res)
        };
        // 加载失败了需要做一个错误图片的占位
        el.onerror = (err) => {
          console.log('加载失败', err);
          el.src = errorImg
        }
      }
    })
    el.Intersection.observe(el)
  },
  unmounted(el, binding) {
    el.Intersection.unobserve(el)
  }
}

// directives/index.js
import layload from "./layload"
// 自定义指令对象,用于遍历注册
const directives = {
  layload
}
// 批量注册指令并暴露到main.js中去便于注册
export default {
  install(app) {
    Object.keys(directives).forEach((key) => {
      app.directive(key, directives[key])
    })
  }
}

// main.js中引入以下代码
 
// 引入并使用自定义指令
import directive from './directives'
app.use(directive);

<!-- 自定义指令 -->
<template>
  <h4>图片懒加载自定义指令</h4>
  <div class="imgBox">
    <img class="image" v-layload="img" v-for="img in imgList" :key="img">
  </div>
</template>

<script setup>
import { ref } from 'vue'
const imgList = [
  {
    src: "http://ashuai.work:10000/imgSrc/html.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/css.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/js.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/nodejs.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/webpack.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/vue.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/react.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/angular.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/ie.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/chrome.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/firefox.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/safari.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/edge.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/http.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/uniapp.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/wx.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/leetcode.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/java.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/spring.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/mybatis.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/redis.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/mysql.png",
  },
  {
    src: "http://ashuai.work:10000/imgSrc/oracle.png",
  },
  {
    src: "占位",
  }
]

const handleSizeChange = (val) => {
  console.log(`${val} items per page`)
}
const handleCurrentChange = (val) => {
  console.log(`current page: ${val}`)
}
</script>
<style scoped>
.demo-pagination-block+.demo-pagination-block {
  margin-top: 10px;
}

.demo-pagination-block .demonstration {
  margin-bottom: 16px;
}

.imgBox {
  width: 100%;
  display: flex;
  justify-content: flex-start;
  flex-wrap: wrap;
}

.image {
  width: 200px;
  height: 200px;
}
</style>

很多问题有多种解决方案,深入探究,前进。

积跬步,至江河。加油ヾ(◍°∇°◍)ノ゙

相关推荐
刚刚好ā19 分钟前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue
yqcoder2 小时前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript
会发光的猪。2 小时前
css使用弹性盒,让每个子元素平均等分父元素的4/1大小
前端·javascript·vue.js
天下代码客3 小时前
【vue】vue中.sync修饰符如何使用--详细代码对比
前端·javascript·vue.js
周全全3 小时前
Spring Boot + Vue 基于 RSA 的用户身份认证加密机制实现
java·vue.js·spring boot·安全·php
Domain-zhuo3 小时前
什么是JavaScript原型链?
开发语言·前端·javascript·jvm·ecmascript·原型模式
小丁爱养花4 小时前
前端三剑客(三):JavaScript
开发语言·前端·javascript
ZwaterZ4 小时前
vue el-table表格点击某行触发事件&&操作栏点击和row-click冲突问题
前端·vue.js·elementui·c#·vue
码农六六4 小时前
vue3封装Element Plus table表格组件
javascript·vue.js·elementui
徐同保4 小时前
el-table 多选改成单选
javascript·vue.js·elementui