首頁  >  文章  >  微信小程式  >  小程式載入器的實作:按需預先載入遠端圖片資源

小程式載入器的實作:按需預先載入遠端圖片資源

不言
不言原創
2018-09-04 17:16:052212瀏覽

本篇文章帶給大家的內容是關於小程式載入器的實作:按需預先載入遠端圖片資源,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

最近做H5開發遇到個問題,為了防止頁面開啟時,出現大圖載入緩慢的情況,寫了一個圖片資源管理器,今天順便實現了一下小程式版。

特別說明一下,小程式由於資源包大小限制,許多圖片資源會存放到CND圖片伺服器上,為了實現小程式初始化時按需載入遠端圖片資源,實作了以下載入器,希望能解決部分小程式新人開發者預先載入圖片的苦惱。

特別強調:

本載入器為初級版本,暫未研究其他實作方式,目前實作方式需要在微信公眾平台- >設定->downloadFile合法網域名稱,中新增想要載入的圖片所在伺服器合法網域。

原則介紹:

使用小程式自帶API讀取遠端圖片資源:

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、載入檔案:

const ImageLoader = require('./utils/ImageLoader.min.js');
const ImageSource = require('./imageSource.js');

ImageLoader.min.js 為載入器原始檔。

imageSource.js 為圖片資源路徑檔。

2、建立ImageLoader物件。

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)原始碼:

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)原始碼:

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形式把圖片路徑寫入,如:

"single1": "ghost.4449aa4.png"

2、類似pages目錄把每個頁面的遠端資源寫入到對應位置下,方便引用和管理,如:

"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、直接以數組方式把圖片堆放在一個數組裡,如:

"imageList": [
 "ghost.4449aa4.png",
 "ghost.4449aa4.png",
 "ghost.4449aa4.png",
 "ghost.4449aa4.png",
 "ghost.4449aa4.png"
 ]

4、隨意的資源數組,物件嵌套,如:

"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欄位的說明:

new ImageLoader({
base: ImageSource.BASE,
source: [ImageSource],
loading: res => {
// 可以做进度条动画
console.log(res);
},
loaded: res => {
// 可以加载完毕动画
console.log(res);
}
});

source欄位接受一個Array類型的參數,以上文中imageSource.js中的設定來說,寫了很多不同格式的數據,使用

const ImageSource = require('./imageSource.js');

引入後,可以直接使用ImageSource來讀取各個部分的數據,因此在配置source字段時可以直接把整個ImageSource物件放入進去

source: [ImageSource]

也可以根據專案需求只載入其中一部分資源,如:

source: [ImageSource.imageList, ImageSource.single2]

這樣載入器在執行時就會只載入source中寫入的部分,而不是整個ImageSource。

最後,在載入過程中如果過於耗時,可以選擇在每個頁面的onLoad裡單獨載入資源,做法類似於在app裡調用,本文的範例是寫在app.js的onLaunch中。如果載入時間過長可以做一個進度條或載入動畫,優化啟動體驗。預先載入過的圖片會在微信記憶體中快取一到小程式進程關閉,因此在隨後的頁面中可以直接使用圖片。

const app = getApp();
const imgSource = require('../../imageSource.js');
Page({
 data: {
 base: imgSource.BASE,
 src: imgSource.single1
 },
 onLoad: function () {
 console.log(imgSource)
 }
})

頁面上的Image會立即顯示,不需要重新發起載入圖片請求。

相關推薦:

JS實作圖片預先載入無需等待

#又一個小巧的圖片預載類別_圖象特效

以上是小程式載入器的實作:按需預先載入遠端圖片資源的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn