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

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>

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

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

相关推荐
一雨方知深秋20 分钟前
智慧商城:封装getters实现动态统计 + 全选反选功能
开发语言·javascript·vue2·foreach·find·every
海威的技术博客23 分钟前
关于JS中的this指向问题
开发语言·javascript·ecmascript
王解37 分钟前
Vue CLI 脚手架创建项目流程详解 (2)
前端·javascript·vue.js
刘大浪40 分钟前
vue.js滑动到顶便锁定位置
前端·javascript·vue.js
ordinary901 小时前
指令-v-for的key
前端·javascript·vue.js
前端Hardy2 小时前
HTML&CSS:酷炫的3D开关控件
前端·javascript·css·3d·html
小马超会养兔子2 小时前
如何写一个数字老虎机滚轮
开发语言·前端·javascript·vue
Web打印2 小时前
web打印插件 HttpPrinter 使用半年评测
javascript·json·firefox·jquery·html5
武昌库里写JAVA2 小时前
使用React Strict DOM改善React生态系统
数据结构·vue.js·spring boot·算法·课程设计
devotemyself2 小时前
vue的ElMessage的css样式不生效
前端·css·vue.js