性能优化—图片懒加载

1,696 阅读3分钟

图片懒加载是一种前端性能优化技术,通过延迟加载不在视窗内的图片,减少页面初始加载时间和带宽消耗。

浏览器渲染过程

  1. 下载HTML和CSS:浏览器通过HTTP协议下载HTML文档和CSS样式表。

  2. 建立DOM树和渲染树

    • HTML标签解析成DOM树。
    • CSS解析成渲染树。
    • DOM树和渲染树结合生成最终页面。
  3. 线程机制

    • JavaScript是单线程的,而浏览器是多线程的。
    • 浏览器会为imglinkscript标签启动新的下载线程。
    • 过多的并发线程可能导致阻塞。

性能优化

  • 优化重点在于尽快显示首屏内容。
  • 图片懒加载技术主要用于延迟加载不在视窗内的图片。

实现步骤

  1. 手动控制图片加载

    • img标签的src属性会立刻触发图片下载,不适用于懒加载。
    • 使用自定义属性(如data-src)来存储图片地址。
  2. 懒加载逻辑

    • 当页面滚动到一定位置时,加载该位置的图片。
    • 使用dataset属性来存储和获取图片地址。
    • 监听scroll事件,在合适的时机加载图片。
  3. 获取图片标签和数量

    const imgs = document.getElementsByTagName('img');
    const num = imgs.length;
    

    我们通过getElementsByTagName方法获取所有的img标签,并存储其数量。

  4. 首次加载可视区内的图片

    document.addEventListener('DOMContentLoaded', () => {
        loadImage();
    });
    

    当DOM内容加载完成时,立即调用loadImage函数来加载可视区内的图片。

  5. 加载图片的函数

    javascript
    复制代码
    function loadImage() {
        console.log('hahaha');
        let screenHeight = document.documentElement.clientHeight;
        let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    
        for (let i = 0; i < num; i++) {
            if (imgs[i].offsetTop < screenHeight + scrollTop) {
                setTimeout(() => {
                    imgs[i].src = imgs[i].dataset.src;
                    let n = i + 1;
                    if (n === num) {
                        console.log("所有图片加载完毕");
                        window.removeEventListener('scroll', throttleLayLoad);
                    }
                }, 1000);
            }
        }
    }
    
    • 获取视窗高度和滚动条的偏移量。
    • 遍历所有图片,如果图片的顶部位置在视窗内,则设置其src属性为data-src的值。
    • 使用setTimeout模拟延迟加载。
    • 检查是否所有图片加载完毕,如果是,则移除滚动事件监听器。
  6. 使用节流技术优化滚动事件

    const throttleLayLoad = _.throttle(loadImage, 500);
    window.addEventListener('scroll', throttleLayLoad);
    
    • 使用Lodash的throttle函数将loadImage函数进行节流,确保在滚动时每隔500ms最多执行一次。
    • 添加滚动事件监听器,调用节流后的loadImage函数。

优化建议

  1. 去掉不必要的setTimeout

    • 当前代码中使用setTimeout延迟1秒加载图片,这是模拟网络延迟的做法,在实际应用中可能不需要。
  2. 检查图片是否已经加载

    • 添加一个检查,避免重复加载已经加载的图片。

修改后的代码如下:

<script>
    // 获取所有img标签
    const imgs = document.getElementsByTagName('img');
    const num = imgs.length;

    // 当首次进入页面时,需要加载当前屏幕的图片
    document.addEventListener('DOMContentLoaded', () => {
        loadImage();
    });

    // 加载图片的函数
    function loadImage() {
        let screenHeight = document.documentElement.clientHeight;
        let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;

        for (let i = 0; i < num; i++) {
            if (imgs[i].offsetTop < screenHeight + scrollTop && !imgs[i].src) {
                imgs[i].src = imgs[i].dataset.src;
                let n = i + 1;
                if (n === num) {
                    console.log("所有图片加载完毕");
                    window.removeEventListener('scroll', throttleLayLoad);
                }
            }
        }
    }

    // 使用lodash的throttle函数来节流,减少滚动事件处理的频率
    const throttleLayLoad = _.throttle(loadImage, 500);
    // 监听滚动事件
    window.addEventListener('scroll', throttleLayLoad);
</script>

通过这些讲解和优化,你应该对懒加载的实现有了更深入的理解。