优化系列之「图片懒加载」

您所在的位置:网站首页 vue大量数据渲染页面性能阻塞 优化系列之「图片懒加载」

优化系列之「图片懒加载」

2023-06-12 11:32| 来源: 网络整理| 查看: 265

前言

在此之前我们先了解下js中几个和滚动相关的属性。

offsetTop :当前元素到 offsetParent 的距离。 offsetParent:距离当前元素最近的一个有定位的祖宗元素,如果没有默认是body。 offsetWidth: width + 左右padding + 左右border offsetHeight: height + 上下padding + 上下border

image.png

clientWidth: width + 左右padding clientHeight: height + 上下padding clientTop = boder.top(上边框的宽度) clientLeft = boder.left(左边框的宽度)

image.png

scrollWidth:获取指定标签内容层的真实宽度(可视区域宽度+被隐藏区域宽度) scrollHeight:获取指定标签内容层的真实高度(可视区域高度+被隐藏区域高度) scrollTop: 内容层顶部到可视区域顶部的距离 scrollLeft: 内容层左端 到 可视区域左端的距离

image.png

案例实现 原理

当有很多图片的时候,如果选择一次性渲染所有图片,非常的耗费性能,这个时候优先加载可视区域内的图片,其他图片当用户滑动到可视区域再进行加载的技术就是图片懒加载。

思路分析

实现图片懒加载的方式有很多种,这里介绍的是利用图片的offsetTop特性。上面介绍了offsetTop等于当前元素到offsetParent的距离,这里我们可以将需要展示图片的窗口设置定位,当图片的offsetTop < scrollTop + clientHeight 的时候代表当前的图片已经出现,那么此时就去加载当前图片。

image.png

在vue中实现 这里用循环的形式模拟后端图片资源 export default function getPngImg(num) { if (typeof num !== "number" || num < 1) return let imgs = [] for (let i = 0; i < num; i++) { let src = `https://robohash.org/${i}.png` imgs.push(src) } return imgs } 将真实的图片地址存储在data-src中 import getPngImg from "../Imgs/production-img.js"; export default { setup() { return { imgSrcs: getPngImg(10), }; }, }

这里用 data-src 暂时设置为真实的图片,方便后面替换,可以将 src 设置为 loading 图片,我这里没有找到 loading 图片就没有设置。

将 data-src 地址替换 src 图片地址 mounted() { this.lazyLoad(); this.$refs.box.addEventListener("scroll", this.handleScroll, true); }, methods: { handleScroll() { debounce(this.lazyLoad, 100); }, lazyLoad() { const imgs = this.$refs.image; const scrollTop = this.$refs.box.scrollTop; const clientHeight = this.$refs.box.clientHeight; for (var i = 0; i < imgs.length; i++) { if (clientHeight + scrollTop > imgs[i].offsetTop) { imgs[i].src = imgs[i].getAttribute("data-src"); } } }, },

因为scroll事件触发的非常频繁,这里面使用了一个防抖函数,也可以使用节流函数,具体的防抖函数写法如下:

/** * 防抖函数 * * @param fn - 目标函数 * @param timer - 等待时间 */ export default function debounce(fn, timer) { if (Object.prototype.toString.call(fn).slice(8, -1) !== "Function" || typeof timer !== "number") return clearTimeout(debounce.T) debounce.T = setTimeout(() => { fn() }, timer) } 也可以使用 vue-lazyload 插件实现 安装插件 npm install vue-lazyload --save-dev 在main.js文件中引入并使用 import VueLazyload from 'vue-lazyload' Vue.use(VueLazyload) 修改图片显示方式为懒加载(将 :src="xxx" 属性直接改为v-lazy="xxx")


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3