聊聊图片预加载

聊聊图片预加载

关于图片的加载,不同的需求有不同的实现,比如图片过多时候的懒加载,为了保证效果的预加载。

如何进行图片的预加载

前端实现图片的预加载,其实是利用了浏览器的缓存,我们通过 a 标签来提前加载图片,如下:

js 复制代码
  const img = new Image() 
  img.src = '链接' 
  img.onload = function(){ 
      console.log('加载完成')
  }

预加载的策略

在实际的业务中,需求不同,加载的策略不尽相同。

场景一:贪婪加载

刚进入页面有 loading,需要将后面的图片全部加载完成。如进入 h5 游戏的时候,需要把后面用到的人物背景图片都加载出来。

这个时候我们不考虑带宽的问题,一次性加载所有的图片。

将每次加载图片封装成一次 promise:

js 复制代码
new Promise((reslove,reject)=>{ 
    const img = new Image() 
    img.src = '链接' 
    img.onload = onerror = resolve 
 })

再使用 promise.all 进行全加载

js 复制代码
Promise.all([...])

场景二:部分加载

正常展示当前页面,但是下个页面的图片可以先偷偷加载进来,同时不要影响当前页面正常图片的加载。

这时候我们需要考虑带宽,不能一次性使用加载图片拉满,这样会导致页面加载的图片加载不出来。可以使用批量加载,比如每次加载 5 张,加载完 5 张之后再加载下 5 张。这样如果当前页面如果有图片也可以正常展示加载。

具体实现类似分页一样,获取要加载图片里面的 5 张,进行加载,直到加载结束。

js 复制代码
// 总任务 
function loadImages(list){ 
    const pageSize = 5 
    const pageNum = 0 
    return new Promise((reslove,reject)=>{ 
        function run(){ 
            Promise.all(genetateTasks(list,pageSize,paegNum)).then(()=>{ 
                pageNum++ 
                const hasLength = pageSize * pageNum 
                if(totalNum > hasLength){ 
                    run() 
                }else { 
                    reslove(true) 
                } }) 
           } 
           run() 
 }) }

子任务处理:

js 复制代码
// 子任务 
function genetateTasks(list,pageSize,pageNum){
    const promiseArr = [] 
    const start = pageNum * pageSize 
    const end = (pageNum + 1) * pageSize - 1 
    for(let i = start;i<end;i++){ 
        const p = new Promise((reslove,reject)=>{ 
            const img = new Image() 
            img.src = list[i] 
            img.onload = img.onerror = reslove 
         }) 
         promiseArr.push(p) 
    } 
    return promiseArr 
}

注意点

  • 在移动端,如果使用贪婪加载,可能会导致你的 loading 图片都没有加载出来(因为都去加载预加载的图片去了),需要将加载图片的逻辑放在 window.load 事件之后
  • 在部分加载的时候,如果需要保证当前页面的效果,可以在当前页面图片加载之后再开始加载(可以使用 imagesloaded)

推荐

imagesloaded - 用来判断当前页面图片是否加载好

preloadJS - 用来预加载一些文件,除了图片,还有js、css等

相关推荐
十一吖i29 分钟前
Vue3项目使用ElDrawer后select方法不生效
前端
只可远观30 分钟前
Flutter目录结构介绍、入口、Widget、Center组件、Text组件、MaterialApp组件、Scaffold组件
前端·flutter
周胡杰32 分钟前
组件导航 (HMRouter)+flutter项目搭建-混合开发+分栏效果
前端·flutter·华为·harmonyos·鸿蒙·鸿蒙系统
敲代码的小吉米1 小时前
前端上传el-upload、原生input本地文件pdf格式(纯前端预览本地文件不走后端接口)
前端·javascript·pdf·状态模式
是千千千熠啊1 小时前
vue使用Fabric和pdfjs完成合同签章及批注
前端·vue.js
da-peng-song1 小时前
ArcGIS Desktop使用入门(二)常用工具条——数据框工具(旋转视图)
开发语言·javascript·arcgis
九月TTS1 小时前
TTS-Web-Vue系列:组件逻辑分离与模块化重构
前端·vue.js·重构
我是大头鸟2 小时前
SpringMVC 内容协商处理
前端
Humbunklung2 小时前
Visual Studio 2022 中添加“高级保存选项”及解决编码问题
前端·c++·webview·visual studio
墨水白云2 小时前
nestjs[一文学懂nestjs中对npm功能包的封装,ioredis封装示例]
前端·npm·node.js