图片懒加载技术详解:提升网页性能与用户体验
图片懒加载
图片懒加载(Lazy Loading)是一种网页优化技术,用于提高页面加载速度和提升用户体验。
核心思想:在用户浏览网页时,并不立即加载所有的图片,而是当图片即将进入可视区域(即用户滚动到图片位置时),才开始加载该图片。这样可以减少初始页面加载时间,特别对于包含大量图片的长页面来说,效果显著。
像你逛的京东网或者淘宝的时候,就会发现当你滑动鼠标的时候,鼠标滚动到的地方的图片才会被加载出来。
实现图片懒加载的方法
-
JavaScript监听滚动事件:这是最常用的懒加载实现方式。通过监听滚动事件,计算图片元素距离浏览器顶部的距离与窗口高度,判断图片是否处于或即将进入可视区域,从而决定是否加载该图片。
-
Intersection Observer API:这是一种更现代、性能更好的懒加载技术。Intersection Observer API 可以监听一个元素何时进入或离开另一个元素的可视区域,不需要频繁地计算和比较位置,因此相比监听滚动事件更加高效。
-
使用第三方库:有很多成熟的JavaScript库可以帮助实现图片懒加载,如lozad.js、layzr.js等。这些库通常封装了上述技术,提供简单易用的API,只需要按照文档引入和配置就可以。
懒加载的基本步骤如下:
-
初始化懒加载: 在页面加载时,对所有需要懒加载的图片进行处理,通常将它们的
src
属性替换为一个占位图或者数据URI,同时保存实际图片URL到data-src
或其他自定义属性中。 -
检测图片是否可见:通过上述提到的方法监听页面滚动或使用Intersection Observer API来检测图片元素是否进入可视区域。
-
加载图片:当检测到图片应被加载时,将
data-src
中的真实图片URL赋值给src
,触发图片加载。 -
处理加载完成与失败:可选地,可以添加加载成功的回调函数来处理图片加载完成后的操作,如应用动画效果;同时,也应该考虑图片加载失败的情况,准备备选方案或错误提示。
懒加载不仅适用于图片,还可以应用于视频、iframe等内容的延迟加载,是提升网页性能和用户体验的有效手段之一。
代码实现
html部分
准备好很多张图片,这里我放了11张图片
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567641974410_img_000" >
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567641293753_img_png">
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567642423719_img_000">
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190808/v2_1565254363234_img_jpg">
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567642425030_img_000">
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567642425101_img_000">
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567642425061_img_000">
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190904/v2_1567591358070_img_jpg">
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567640518658_img_png">
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567641974410_img_000">
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567641974454_img_000">
将真正的图片URL放到data-src
中,在src
属性中放的是一个占位图,点进去占位图链接你就会发现这是一张很小的图片,宽度和高度都只有1像素,这样打开图片会非常的快,只需要下载这张图片地址就可以。这种做可以让浏览器在初次渲染页面时不会立即请求图片的实际内容。
css部分
body{
background-color: #000000;
}
img {
display: block;
margin-bottom: 50px;
width: 400px;
height: 400px;
}
将背景颜色设置为灰色,在img
标签中添加属性,将图片作为块级元素显示,图片独占一行,为图片添加底部外边距为50px,图片大小设置宽高都为400px。样式图片如下所示:
JavaScript部分
<script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
<script>
// 获取所有的img元素
const imgs = document.getElementsByTagName('img');
// 记录img元素的数量
const num = imgs.length;
// 使用lodash的throttle方法创建一个节流过的lazyload函数
const lazyLoadThrottled = _.throttle(lazyload, 200);
// 当文档加载完成后,开始监听滚动事件,并立即执行一次lazyload函数加载可视区内的图片
document.addEventListener('DOMContentLoaded', () => {
window.addEventListener('scroll', lazyLoadThrottled);
lazyload();
});
// 计数器,记录已加载的图片数量
let loadedCount = 0;
// 图片延迟加载的核心函数
function lazyload(){
// 获取可视窗口的高度
const screenHeight = document.documentElement.clientHeight;
// 获取当前滚动位置
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
console.log(scrollTop);
// 遍历所有图片
for (let i = loadedCount; i < num; i++) {
// 判断图片是否在可视区域内
if (imgs[i].offsetTop < screenHeight + scrollTop){
// 如果在可视区域,则将占位符替换为真实图片地址加载图片
imgs[i].src = imgs[i].getAttribute('data-src');
// 加载计数器加一
loadedCount++;
// 如果所有图片都已加载,则移除滚动事件监听,避免不必要的计算
if(loadedCount === num){
window.removeEventListener('scroll', lazyLoadThrottled);
}
}
}
}
</script>
下面是对上面代码的详细解释:
-
引入Lodash库:通过CDN链接引入了Lodash库的minified版本,这是一个常用的JavaScript实用函数库,提供了许多便捷的函数来处理数组、对象、函数等。
-
获取所有图片元素: 定义一个变量
imgs
,通过document.getElementsByTagName('img')可以获取页面中所有的<img>
元素,并将其存储在imgs
数组中。 -
统计图片数量: 通过代码 const num = imgs.length 计算并存储图片的总数。
-
创建节流函数: 使用lodash库的
throttle
方法包装lazyload
函数,限制该函数在200毫秒内只能执行一次,防止在快速滚动时频繁触发图片加载,减轻服务器负担并优化性能。 -
文档加载完成及监听滚动事件: 当DOM内容加载完成时,添加一个滚动事件监听器,并立即调用一次
lazyload()
函数。这确保了页面初次加载时可视区域内的图片会被加载,同时在用户滚动页面时也能动态加载即将可见的图片。 -
初始化计数器:
let loadedCount = 0;
用于记录已加载的图片数量。 -
核心懒加载函数
lazyload
:- 获取可视窗口的高度和当前滚动位置,以便判断图片是否位于可视区域内。
- 遍历图片数组,从上次加载的位置开始检查(由
loadedCount
指示),以避免重复检查已加载的图片。 - 对于每个图片,使用
offsetTop
属性检查其距离页面顶部的位置,如果小于当前滚动位置加上可视窗口的高度,说明该图片至少部分进入了可视区域。 - 将图片的
src
属性设置为其data-src
属性的值,即替换成真实的图片地址,从而加载图片。 - 每成功加载一张图片,
loadedCount
加一。 - 当所有图片都已加载完毕(即
loadedCount
等于图片总数num
),移除滚动事件的监听器,因为此时无需再监听滚动来触发图片加载。
这段JavaScript代码实现了一个图片懒加载功能,旨在提高页面加载速度和用户体验,尤其是对于包含大量图片的网页。
结语
图片懒加载是前端性能优化的核心,data-src才是真的地址,src只是占位图,希望今天的内容可以给你带来帮助。
转载自:https://juejin.cn/post/7382414191833595919