likes
comments
collection
share

前端性能优化-图片懒加载

作者站长头像
站长
· 阅读数 87

前言

今天我们聊聊又一个前端小知识点,性能优化,怎么实现图片懒加载功能。

图片懒加载

我们知道只要在html中写下了img标签之后,只要网页一加载,就会去src的地址上下载图片,当我们这个网页有很多图片时,比如常见的电商网站,就需要消耗较多资源去下载图片,有可能会造成卡顿,势必会造成用户体验不佳,所以图片懒加载(Lazy Loading)应运而生,它是一种优化网页加载性能的技术,它的工作原理是仅在用户需要查看图片时(如滚动到图片所在的视口范围内)才加载图片资源,而不是在页面初始加载时一次性加载所有图片。这样可以减少初始页面加载时间,提升用户体验。

优化步骤

大致思路:将真实的img地址填在data-src中,src中填入一张消耗资源较小的图片作为占位图。当屏幕滚动到当前图片时,使用getAttribute将data-src中的地址换到src,即可完成图片懒加载。既然有滚动事件,那么我们可以再优化一下,使用节流函数,设置一个时间间隔,确保在这个间隔内图片加载只能被调用一次。

HTML

<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>标签初始时都指向一个占位图片,通过data-src属性保存实际的图片地址,实际图片将在懒加载时被加载。

JavaScript

获取图片列表和数量

const imgList = document.getElementsByTagName('img');
const num = imgList.length;
let n = 0;

通过getElementsByTagName获取所有img元素,并记录其数量以及一个初始的计数器n

事件监听

window.addEventListener('scroll', throttle(lazyload, 200));
document.addEventListener('DOMContentLoaded', () => {
    console.log('DOMContentLoaded');
    lazyload();
});
  • 当页面滚动时,通过throttle函数节流后调用lazyload函数。
  • 当页面内容加载完成时(DOMContentLoaded事件),立即执行一次lazyload,确保初始可见区域的图片被加载。

懒加载函数

function lazyload() {
    let screenHeight = document.documentElement.clientHeight;
    let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;

    for (let i = n; i < num; i++) {
        if (imgList[i].offsetTop < screenHeight + scrollTop) {
            imgList[i].src = imgList[i].getAttribute('data-src');
            n = i + 1;
            if (n === num) {
                window.removeEventListener('scroll', throttleLazyload);
            }
        }
    }
}
  • 获取视口高度和滚动距离。
  • 遍历图片列表,如果图片的位置在当前视口内,则加载图片(将data-src属性值赋给src属性)。
  • 更新已加载图片的计数器n,如果所有图片都加载完成,则移除滚动事件监听器。

节流函数

function throttle(func, limit) {
    let inThrottle;
    return function() {
        const context = this;
        const args = arguments;
        if (!inThrottle) {
            func.apply(context, args);
            inThrottle = true;
            setTimeout(() => inThrottle = false, limit);
        }
    };
}
  • throttle函数限制了函数调用的频率,防止scroll事件过于频繁触发lazyload,提高性能。

OK,到此我们就完成了图片懒加载功能。大家有没有发现像防抖节流等等这些基本函数我们需要写很多次,很是麻烦,不用担心,像这种功能早就有库函数已经帮我们封装好了。

Lodash.js

Lodash.js 是一个功能强大且广泛使用的 JavaScript 工具库,提供了大量的实用函数,帮助开发者处理数组、对象、字符串等常见的数据操作。Lodash 的设计初衷是提高 JavaScript 编程的效率和简洁性。

快速入门

使用 CDN 直接引用

<script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

在项目中引入 Lodash 后,就可以使用 Lodash 提供的各种函数,这里我们结合图片懒加载使用节流函数,主要注意调用方式。

const imgList = document.getElementsByTagName('img');
const num = imgList.length;
// console.log(imgList);
let n = 0;
// 注册在scroll事件中的触发函数
const throttleLazyload = _.throttle(lazyload, 200)
window.addEventListener('scroll', throttleLazyload)
// DOMContentLoaded html和css页面加载完成时触发,保证第一次页面的图片不用滚轮加载图片
document.addEventListener('DOMContentLoaded', () => {
            console.log('DOMContentLoaded');
            lazyload()
})
function lazyload() {
            // 获取可视区域一屏的高度
            let screenHeight = document.documentElement.clientHeight;
            console.log(screenHeight);
            // 获取滚动条滚动的距离 多浏览器适配
            let scrollTop = document.documentElement.scrollTop || 						document.body.scrollTop;
            console.log(scrollTop);
            for (let i = n; i < num; i++) {
                if(imgList[i].offsetTop < screenHeight + scrollTop) {
                    imgList[i].src = imgList[i].getAttribute('data-src');
                    // 记录已经加载过的图片的下标
                    n = i + 1;
                    if(n === num) {
                        // console.log('所有图片加载完成');
                        window.removeEventListener('scroll', throttleLazyload)
                    }
                }
        }
}

总结

当我们了解图片懒加载的原理后,可以使用一些更为简便的库函数来帮我们实现,重复造轮子是编程的一个大忌。

转载自:https://juejin.cn/post/7379934759877984271
评论
请登录