如何实现图片预加载

1,722 阅读2分钟

图片预加载

需求

有个图片很大,在B页面渲染,当用户进入B页面,希望能够马上呈现,而不是慢慢加载出来。

解决

我们可以利用浏览器的缓存机制,多个页面访问同一张地址的图片,只会请求图片一次。
可以在A页面偷偷加载B页面的图片。

基础版本

在A页面中模拟图片渲染

    //要加载的图片地址,最好选大一点的,效果可以看得更明显
    let imgs = [
      'http://119.45.xx.xx/img/1.jpg',
      'http://119.45.xx.xx/img/2.jpg'
    ]
    //遍历图片,生成图片dom,模拟加载
    for (let img of imgs) {
      //生成图片对象
      let image = new Image()
      image.src = img
      console.log('加载中。。请稍等')
      //给图片增加渲染完成事件,是异步的
      image.onload = () => {
        count++
        if(imgs.length === count){ //当渲染个数与图片相同时,所有图片加载完成
          console.log(count, '所有图片渲染完成')
        }
      }
    }

B页面放图片就ok了,会之前读取A页面缓存的图片

<img src='http://119.45.xx.xx/img/1.jpg'>
<img src='http://119.45.xx.xx/img/2.jpg'>

  • chrome会从内存或者磁盘读取缓存过的 image.png

进阶版本

新建一个imagePreloader.js

//创建单个图片加载的方法-包成一个promise
const imgPreloader = url => {
  return new Promise((resolve, reject) => {
    let image = new Image();
    image.onload = () => {
      resolve('图片加载成功');
    };
    image.onerror = () => {
      reject('图片加载出错');
    };
    image.src = url
  });
}

/**
 * 遍历图片路径,利用promise.all进行并行响应
 * @param imgs 图片路径数组
 * @returns {Promise<unknown[]>}
 */
const allImgPreloader = imgs => {
  let promiseArr = []
  imgs.forEach(src => {
    console.log(28, src)
    promiseArr.push(imgPreloader(src))
  })
  return Promise.all(promiseArr)
}

export default allImgPreloader

在你需要预加载的地方使用

//引入刚刚写加载的方法
import allImgPreloader from 'imagePreloader.js'


let imgs = [ //图片路径数组,可以抽出去,这里就不抽了
  'http://119.45.xx.xx/img/1.jpg',
  'http://119.45.xx.xx/img/2.jpg'
]

console.log('开始渲染---渲染中。。。')
const res = allImgPreloader(imgs)
res.then(val=>{
  console.log('渲染成功')
  console.log(23, val)//['图片加载成功', '图片加载成功']
})

用法

参考

promise.all用法