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

232 阅读1分钟

展示效果

图片懒加载.gif

1. intersectionObserver API 实现

/** 图片懒加载
 * @param {nodeList} 传入要监听的节点元素列表集合
 * @return {void}
 */
function imgLazyLoad(nodeList) {
    if (Object.prototype.toString.call(nodeList) !== "[object NodeList]") return;
    
    const io = new IntersectionObserver(inters => {
        inters.forEach(item => {
            // 进入可视区域
            if (item.isIntersecting) {
                // 替换成真实的src地址
                item.target.src = item.target.dataset.src;
                // 元素加载后停止(解绑)监听该元素
                io.unobserve(item.target);
            }
        });
    });

    // 节点类数组转成dom元素数组
    const elements = [...nodeList];
    // 监听每一个元素
    elements.forEach(el => io.observe(el));
}

imgLazyLoad(document.querySelectorAll("li"));

2. 滚动事件 onscroll + throttle 实现


/** 节流
 * @param {Function} fn 执行的回调函数
 * @param {number} delay 延迟时间
 */
function throttle(fn, delay = 800) {
    let lastTime = 0;
    return function () {
        let nowTime = Date.now();
        if (nowTime - lastTime > delay) {
            fn.apply(this);
        }
        lastTime = nowTime;
    };
}

/** 图片懒加载 */
function imgLazyLoad() {
    const imgs = document.querySelectorAll("img");
    // 获取视口的高度
    const viewHeight = document.documentElement.clientHeight;

    // 获取滚动条高度
    const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop;

    for (let i = 0; i < imgs.length; i++) {
        const offsetHeight = imgs[i].offsetTop;
        if (viewHeight + scrollHeight > offsetHeight) {
            const src = imgs[i].dataset.src;
            imgs[i].src = src;
        }
    }
}

window.addEventListener("scroll", throttle(imgLazyLoad));
window.addEventListener("load", throttle(imgLazyLoad));