前端优化——图片预加载

1,462 阅读1分钟

什么是图片预加载(加载时机问题)

将所有所需的资源提前请求加载到本地,这样后面在需要用到时就直接从缓存取资源。

为什么要用图片预加载(优化用户体验)

预加载:如果一个页面资源过多,页面可能会会长时间白屏,直到所有内容加载完毕。在网页全部加载之前,对一些主要内容进行加载,以提供给用户更好的体验,减少等待的时间。

具体实现

1、使用Image对象
 window.onload = function () {
      let div = document.createElement('div')
      document.body.appendChild(div)
      let myImage = function () {
        let dummy = document.createElement('img') // 用来加载占位图
        div.appendChild(dummy)
        let img = new Image() //负责拉取大图
        img.onload = function () { //大图拉取完渲染到页面上
          dummy.remove()
          div.insertAdjacentHTML('beforeend', img.outerHTML)
          // div.innerHTML = img.outerHTML
        }
        return {
          setSrc: function (src) {
            // 小图
            dummy.src =
              'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F01f22259a8efb2a8012028a96414b6.png%401280w_1l_2o_100sh.png&refer=http%3A%2F%2Fimg.zcool.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1647658454&t=67f1c2e9d0eb313acc7ec2ab399362e3'
            img.src = src
          }
        }
      }()
      // 大图
      myImage.setSrc('https://t7.baidu.com/it/u=2168645659,3174029352&fm=193&f=GIF')
    }
相关阅读:

Image()HTMLImageElementImage onload 事件outerHTMLinsertAdjacentHTML

效果:

把网速调成slow 3G

Snipaste_2022-02-17_11-17-03.jpg

加载占位图

Snipaste_2022-02-17_11-17-32.jpg

加载大图

Snipaste_2022-02-17_11-17-51.jpg

用代理模式重构
    class ClientObj {
      constructor(src) {
        this.src = src
      }
      setSrc() {
        const img = document.createElement('img')
        img.src = this.src
        return img
      }
    }
    class ProxyObj {
      constructor(src, dummySrc) {
        this.src = src
        this.dummySrc = dummySrc
      }
      setSrc() {
        const div = document.createElement('div')
        const dummy = new Image()
        dummy.src = this.dummySrc
        div.appendChild(dummy)
        document.body.appendChild(div)
        const img = new ClientObj(this.src).setSrc()
        img.onload = () => {
          dummy.remove()
          div.innerHTML = img.outerHTML
        }
      }
    }
    window.onload = () => {
      new ProxyObj('https://t7.baidu.com/it/u=2168645659,3174029352&fm=193&f=GIF',
        'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F01f22259a8efb2a8012028a96414b6.png%401280w_1l_2o_100sh.png&refer=http%3A%2F%2Fimg.zcool.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1647658454&t=67f1c2e9d0eb313acc7ec2ab399362e3'
      ).setSrc()
    }
2、使用XHR对象 (存在跨域问题,但会颗粒度更小)
    XHR.onreadystatechange = request;
    XHR.onprogress = progress;
    XHR.open("GET", "http://image.baidu.com/mouse,jpg", true);
    XHR.send();

    function request() {
      if (XHR.readyState == 4 && XHR.status == 200) {
        const responseText = XHR.responseText;
      } else {
        console.log("Request was unsuccessful:" + XHR.status);
      }
    }
    // 进度条
    function progress(e) {
      e = e || event;
      if (e.lengthComputable) {
        console.log("Received" + e.loaded + "of" + e.total + "bytes")
      }
    }
相关阅读:

XHRAjaxonprogress

3、使用 PreloadJS库
4、使用HTML标签
<img src="http://pic26.nipic.com/20121213/6168183 0044449030002.jpg" style="display:none"/>