基于代理模式实现图片的懒加载

371 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,点击查看活动详情

前情提要

  • 前面咱们已经讲到了代理设计模式
  • 今天就对于代理模式进行一个新的拓展:实现一个图片的懒加载

为什么要进行图片懒加载?

  • 想必大家在开发web应用的时候应该会遇到很多需要我们加载图片的地方,尤其是面向C端的产品,那么为了保证网站的视觉效果,往往会采用比较大的图片。但是这同样也带来了性能问题。
  • 解决上述性能问题的方式有很多,比如cdn加速,比如采用第三发给存储,比如采用既能保证图片的质量,体积又小的图片格式。
  • 除了上述的方式之外,还有一种更偏向用户体验的性能提升,那便是懒加载。将图片的加载与网站加载进行错峰处理,然后在图片没有加载出来前先用本地一个比较小的统一的图片进行代替,等图片加载完成后再进行替换。

普通版图片懒加载

// 如果是在vue中,这里便不需要在onload里写,直接在声明周期里执行就可以了。
window.onload = function () {
    const imgLazy = (function() { // 这里采用了立即执行的方式,方便后面的使用
        // 先创建一个img标签,然后插入到body里。实现生产过程中这里需要做一些变动
        const imgNode = document.createElement('img');
        document.body.appendChild(imgNode);
        const img = new Image(); // 创建一个image对象,当接收到真实要加载的图片地址的时候,开始进行加载
        img.onload = function () { // 加载完成后进行地址替换
            imgNode.src = this.src;
        }
        return {
            refreshSrc: function (realSrc) { // 对外暴露的一个方法,接收一个真实的图片地址
                imgNode.src = 'xxxxxxxx'; // 先将默认地址赋值给img标签
                img.src = realSrc; // 然后开始在内存中进行图片的加载。
            }
        }
    })()
    
    imgLazy.refreshSrc('yyyyyyyyyyyyyyy'); // yy...yy为要加载的图片真实地址
}

代理模式版图片懒加载

// 首先创建一个真实的图片地址赋值对象
// 该对象只进行单一的img标签创建以及src赋值
const imgObj = (function() {
    const imgNode = document.createElement("img");
    document.body.appendChild(imgNode);
    return { 
         refreshSrc: function(src) {
             imgNode.src = src;
         }
    }
})()
// 代理对象
// 该对象会先对真实对象进行默认图片地址赋值,通过调用refreshSrc方法。
// 然后等图片加载完成后进行真实图片地址的赋值
const proxyImg = (function() {
    const img = new Image();
    img.onload = function() {
        imgObj.refreshSrc(this.src);
    }
    return { 
        refreshSrc: function(src) {
            imgObj.refreshSrc('xxxxx');
            img.src = src;
        }
    }
})()
proxyImg.setSrc('yyyyyyyy'); // 真实地址

总结

上述的例子更多的是一种示例,帮助理解,如果在实际生产中可能会面临各种各样的需求,可能会需要举一反三的进行定制化封装哦