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

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>

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

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

相关推荐
万物得其道者成2 分钟前
React Zustand状态管理库的使用
开发语言·javascript·ecmascript
小白小白从不日白3 分钟前
react hooks--useReducer
前端·javascript·react.js
下雪天的夏风15 分钟前
TS - tsconfig.json 和 tsconfig.node.json 的关系,如何在TS 中使用 JS 不报错
前端·javascript·typescript
青稞儿21 分钟前
面试题高频之token无感刷新(vue3+node.js)
vue.js·node.js
diygwcom27 分钟前
electron-updater实现electron全量版本更新
前端·javascript·electron
volodyan30 分钟前
electron react离线使用monaco-editor
javascript·react.js·electron
^^为欢几何^^39 分钟前
lodash中_.difference如何过滤数组
javascript·数据结构·算法
Hello-Mr.Wang44 分钟前
vue3中开发引导页的方法
开发语言·前端·javascript
程序员凡尘1 小时前
完美解决 Array 方法 (map/filter/reduce) 不按预期工作 的正确解决方法,亲测有效!!!
前端·javascript·vue.js
北岛寒沫5 小时前
JavaScript(JS)学习笔记 1(简单介绍 注释和输入输出语句 变量 数据类型 运算符 流程控制 数组)
javascript·笔记·学习