小程序开发|小程序制作|小程序开发网

搜索

小程序远程图片资源按需预加载

2022-5-31 18:19| 发布者: 快乐的鱼| 查看: 498| 评论: 2

摘要: 最近做H5开发遇到个问题,为了防止页面打开时,出现大图加载缓慢的情况,写了一个图片资源管理器,今天顺便实现了一下小程序版。特别说明一下,小程序由于资源包大小限制,很多图片资源会存放到CND图片服务器上,为


最近做H5开发遇到个问题,为了防止页面打开时,出现大图加载缓慢的情况,写了一个图片资源管理器,今天顺便实现了一下小程序版。
特别说明一下,小程序由于资源包大小限制,很多图片资源会存放到CND图片服务器上,为了实现小程序初始化时按需加载远程图片资源,实现了以下加载器,希望能解决部分小程序新人开发者预加载图片的苦恼。

特别强调:
本加载器为初级版本,暂未研究其他实现方式,当前实现方式需要在微信公众平台->设置->downloadFile合法域名,中添加想要加载的图片所在服务器合法域名。


(文末有高清图)

原理介绍:
使用小程序自带API读取远程图片资源:
[JavaScript] 纯文本查看 复制代码
wx.getImageInfo({  src: 'images/a.jpg',  success: function (res) {    console.log(res.width)    console.log(res.height)  }})

这个接口可以创建图片组件对象并返回图片加载状态。

加载器用法:

(文末有高清图)
1、在app.js的同级目录下创建一个ImageSource.js作为图片资源的路径管理文件(可以根据情况改为其他文件名称)。
2、在utils文件夹下放入ImageLoader.js或ImageLoader.min.js(附件)。
3、根据需要在对应的文件中创建ImageLoader对象(看下文)。

使用示例:
1、载入文件:
[JavaScript] 纯文本查看 复制代码
const ImageLoader = require('./utils/ImageLoader.min.js');const ImageSource = require('./imageSource.js');


ImageLoader.min.js 为加载器源文件。
imageSource.js 为图片资源路径文件。

2、创建ImageLoader对象。
[JavaScript] 纯文本查看 复制代码
new ImageLoader({      base: ImageSource.BASE,      source: [ImageSource],      loading: res => {        // 可以做进度条动画        console.log(res);      },      loaded: res => {        // 可以加载完毕动画        console.log(res);      }    });


参数:
base : String 图片资源的基础路径 必填 示例: "https://image.example.com/static/images/"
source : Array 需要预加载的图片资源 必填 示例: [ImageSource.banners, ImageSource.imageList]
loading : function 图片加载中的回调方法 非必填 示例:
loaded : funciton 图片记载完成后的回调 非必填 示例:

加载器(ImageLoader.js)源码:
[JavaScript] 纯文本查看 复制代码
let base = 0;let Img = function(src) {  this.src = src;  this.status = false;  this.fail = false;}let loop = (o, res) => {  let tem = Object.keys(o);  tem.map(v => {    if (typeof o[v] === 'object') {      loop(o[v], res);    } else {      if(v === 'BASE') {        base = o[v];      } else {        res.push(o[v]);      }    }  });}function ImageLoader(obj) {  let arr = [];  if(obj.loading) {    this.loadingcallback = obj.loading;  }  if(obj.loaded) {    this.loadedcallback = obj.loaded;  }  if(obj.base) {    base = obj.base  }  this.insert = (item) => {    arr.push(item);  };  this.init = (o) => {    let res = [];    loop(o, res);    console.log(res)    res.map((v) => {      this.insert(new Img(v));    });    this.load();  };  this.load = () => {    this.start = (new Date).getTime();    arr.map((v) => {      let src = base ? base + v.src: v.src;      wx.getImageInfo({        src: src,        success: res => {          v.status = true;        },        fail: err => {          v.fail = true;        }      })    });    let timer = setInterval(() => {      let status = this.isLoaded();      if (status) {          clearTimeout(timer);        }      }, 200);    setTimeout(() => {      clearTimeout(timer);    }, 60000);  };  this.isLoaded = () => {    let status = true,      count = 0,      fail = 0;    arr.map((v) => {      if (!v.status) {        status = false;      } else {        count += 1;      }      if(v.fail) {        status = true;        fail += 1;      }    });    if(status) {      if(this.loadedcallback) {        this.loadedcallback({          status: true,          timecost: (new Date).getTime() - this.start,          success: count,          fail: fail,          totalcount: arr.length        })      }    } else {      if(this.loadingcallback) {        this.loadingcallback({          status: false,          percent: count / arr.length        });      }    }    return status;  };  if(obj.source) {    this.init(obj.source);  }}module.exports = ImageLoader


图片资源路径文件(imageSource.js)源码:
[JavaScript] 纯文本查看 复制代码
module.exports = {    "BASE": "https://img.caibeitv.com/static_project/teacherTest/static/img/",    "single1": "ghost.4449aa4.png",    "single2": "ghost.4449aa4.png",    "single3": "ghost.4449aa4.png",    "single4": "ghost.4449aa4.png",    "pages": {      "index": ["ghost.4449aa4.png", "ghost.4449aa4.png"],      "user": ["ghost.4449aa4.png", "ghost.4449aa4.png"],      "home": ["ghost.4449aa4.png", "ghost.4449aa4.png"],      "login": ["ghost.4449aa4.png", "ghost.4449aa4.png"]    },    "imageList": [      "ghost.4449aa4.png",      "ghost.4449aa4.png",      "ghost.4449aa4.png",      "ghost.4449aa4.png",      "ghost.4449aa4.png"    ],    "folders": {      "page1": "ghost.4449aa4.png",      "page2": "ghost.4449aa4.png",      "inner": [        "ghost.4449aa4.png",        "ghost.4449aa4.png"      ],      "home": {        "poster": "ghost.4449aa4.png"      }    }}


说明:
BASE 字段必填 根据自我需要填写。
其他图片资源支持:
1、直接key:value形式把图片路径写入,如:[JavaScript] 纯文本查看 复制代码
 "single1": "ghost.4449aa4.png"
2、类似于pages目录把每个页面的远程资源写入到对应位置下,方便引用和管理,如:
[AppleScript] 纯文本查看 复制代码
"pages": {      "index": ["ghost.4449aa4.png", "ghost.4449aa4.png"],      "user": ["ghost.4449aa4.png", "ghost.4449aa4.png"],      "home": ["ghost.4449aa4.png", "ghost.4449aa4.png"],      "login": ["ghost.4449aa4.png", "ghost.4449aa4.png"]    },

3、直接以数组方式把图片堆放在一个数组里,如:
[JavaScript] 纯文本查看 复制代码
"imageList": [      "ghost.4449aa4.png",      "ghost.4449aa4.png",      "ghost.4449aa4.png",      "ghost.4449aa4.png",      "ghost.4449aa4.png"    ]

4、随意的资源数组,对象嵌套,如:
[JavaScript] 纯文本查看 复制代码
"folders": {      "page1": "ghost.4449aa4.png",      "page2": "ghost.4449aa4.png",      "inner": [        "ghost.4449aa4.png",        "ghost.4449aa4.png"      ],      "home": {        "poster": "ghost.4449aa4.png"      }    }


这样就完成了整个远程图片资源加载器的配置,可以在new ImageLoader() 对象的 loading, loaded回调中看到图片预加载的最终状态status,数量totalcount,成功加载的图片数量success,加载失败的图片数量fail, 加载图片的总计耗时timecost(单位ms)。

创建ImageLoader对象时source字段的说明:
[JavaScript] 纯文本查看 复制代码
new ImageLoader({base: ImageSource.BASE,source: [ImageSource],loading: res => {// 可以做进度条动画console.log(res);},loaded: res => {// 可以加载完毕动画console.log(res);}});



source字段接受一个Array类型的参数,以上文中imageSource.js中的配置来说,写了很多不同格式的数据,使用[JavaScript] 纯文本查看 复制代码
const ImageSource = require('./imageSource.js');
引入后,可以直接使用ImageSource来读取各个部分的数据,因此在配置source字段时可以直接把整个ImageSource对象放入进去 [JavaScript] 纯文本查看 复制代码
source: [ImageSource]
, 也可以根据项目需要只加载其中一部分资源,如:[JavaScript] 纯文本查看 复制代码
source: [ImageSource.imageList, ImageSource.single2]
。这样加载器在执行时就会只载入source中写入的部分,而不是整个ImageSource。

最后,在加载过程中如果过于耗时,可以选择在每个页面的onLoad里单独加载资源,做法类似于在app里调用,本文的示例是写在app.js的onLaunch中。如果加载时间过长可以做一个进度条或者加载动画,优化启动体验。预加载过的图片会在微信内存中缓存一到小程序进程被关闭,因此在随后的页面里可以直接使用图片。
[JavaScript] 纯文本查看 复制代码
const app = getApp();const imgSource = require('../../imageSource.js');Page({  data: {    base: imgSource.BASE,    src: imgSource.single1  },  onLoad: function () {    console.log(imgSource)  }})

页面上的Image会立即显示,不需要重新发起加载图片请求。
https://github.com/xiongchenf/imgLoader

github上有最新源码及使用方法

个人研究结果,如有错误、不足欢迎批评指正,相互探讨。个人QQ: 837195936 熊





B4010357-5F70-45D7-A4BF-6E40B877208B.png
196E83F2-E122-4B3A-AD60-71ABCACC3C65.png
ImageLoader.min-1.0.2.jsImageLoader.min-1.0.1.js
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

鲜花

握手

雷人

路过

鸡蛋
发表评论

最新评论

引用 xiaoxiao 2022-5-31 19:33
你好,楼主,不行
引用 风琴来 2022-5-31 18:54
谢谢楼主。

查看全部评论(2)

返回顶部