首页 > 网站 > WEB开发 > 正文

前端性能优化之 —— 图片延迟加载 (原理以及实现方式)

2024-04-27 15:08:49
字体:
来源:转载
供稿:网友

前端开发的时候,有些列表页面可能会有很多图片需要加载。一次加载太多图片,会占用很大的带宽,影响网页的加载速度。

这时候我们想到一种方式,让用户浏览到什么地方,就加载该处的图片。

这里写了一个简单的例子,大家可以去体验一下,当然这里考虑到的是最简单的情况。 这里简单的讲解一下这个例子里面的源码

例子查看

DOM 结构

由一个父容器div#lazy-img,里面是图片标签,父容器是可以滚动的,图片有固定高度。大家可以看到,容器内的img元素没有 src 属性,而有一个 data-src 属性。 这是不想让图片提前加载,所以把图片的链接储存到data-src 内。

div#lazy-img img(data-src="https://file.diamondfsd.com/img/9c61bc16-ae02-4f06-a8aa-0501db51eadb.png") img(data-src="https://file.diamondfsd.com/img/9c61bc16-ae02-4f06-a8aa-0501db51eadb.png") img(data-src="https://file.diamondfsd.com/img/9c61bc16-ae02-4f06-a8aa-0501db51eadb.png") img(data-src="https://file.diamondfsd.com/img/9c61bc16-ae02-4f06-a8aa-0501db51eadb.png") img(data-src="https://file.diamondfsd.com/img/9c61bc16-ae02-4f06-a8aa-0501db51eadb.png") img(data-src="https://file.diamondfsd.com/img/9c61bc16-ae02-4f06-a8aa-0501db51eadb.png") img(data-src="https://file.diamondfsd.com/img/9c61bc16-ae02-4f06-a8aa-0501db51eadb.png") img(data-src="https://file.diamondfsd.com/img/9c61bc16-ae02-4f06-a8aa-0501db51eadb.png") img(data-src="https://file.diamondfsd.com/img/9c61bc16-ae02-4f06-a8aa-0501db51eadb.png")PugCopyimg{ width:600px; height:300px; border: 2px solid #eee; background: #ccc;}#lazy-img{ height: 400px; background:#eee; overflow: auto;}CSSCopy

javascript 代码

我们获取容器内所有有 data-src 属性的dom对象,遍历获取他们的相对高度,储存成 { height: imgDom} 格式。然后监听 容器的滚动事件,当滚动的时候,计算当前滚动区域显示的图片dom,并将改 图片dom 的 src 的内容改成我们存储在 data-src 的内容。

var imgContainer = document.getElementById('lazy-img')var imgs = imgContainer.querySelectorAll('[data-src]')var imgHeightDomMapping = {}imgs.forEach(function (img) { imgHeightDomMapping[img.offsetTop + img.clientHeight / 1.5] = img}) // 获取所有 dom 对象相对容器的高度 并储存成 key: height, value: imgDomimgContainer.addEventListener('scroll', function () { showImage()})function showImage () { var currentHeight = imgContainer.clientHeight + imgContainer.scrollTop // 滚动区域的高度 Object.keys(imgHeightDomMapping).forEach(function (imageHeight) { if (currentHeight > imageHeight) { // 判断当前图片是否已经显示 //将图片dom的 `src` 改为 `data-src` 的内容 imgHeightDomMapping[imageHeight].src = imgHeightDomMapping[imageHeight].getAttribute('data-src') } })}showImage() // 主动调用一次 加载首页的JsCopy

这里简单的实现了一个延迟加载,主要是告诉大家原理,可扩展的地方还很多。 例如提前加载 N 张图片,可以包装成一个通用的插件等等。只要大家了解到了原理,那么实现折些都很简单。 这篇文章也算是抛砖引玉,欢迎大家进行讨论。


上一篇:js时间格式化

下一篇:sass循环 each、for

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表