来源
最近写小程序的时候,因为首页有轮播图、广告图等等,导致我的首屏加载太慢了,想着将一部分图片做下本地缓存。
解决办法
- 查询api
- FileSystemManager.saveFile
FileSystemManager.saveFile(Object object)
保存临时文件到本地。此接口会移动临时文件,因此调用成功后,tempFilePath 将不可用。 - wx.getSavedFileList
wx.getSavedFileList(Object object)
获取该小程序下已保存的本地缓存文件列表 - FileSystemManager.removeSavedFile
FileSystemManager.removeSavedFile(Object object)
删除该小程序下已保存的本地缓存文件
- FileSystemManager.saveFile
- 使用localstorage记录缓存文件
- 合理利用接口获取的图片列表(fileList)和当前localstorage的记录
- localstorage存在,且fileList不存在,则删除localstorage的记录,移除本地缓存
- localstorage不存在,且fileList存在,则先给img标签网络请求地址,并且把改图片缓存到本地,加入localstorage以便下次使用
代码(这里使用mpvue开发的小程序,小程序语法自行转化)
callBackBanAd(o) {
let _this = this;
_this.imgArrAd = o.data;
let cacheImgList = wx.getStorageSync("cacheImgList");
let saveFileList = [];// 所有需要缓存的图片
let downloadFileList = [];// 未缓存,需要下载的图片
_this.imgArrAd.forEach(item => {
saveFileList.push(item.image);
let encodeUrl = encodeURIComponent(item.image);// 将图片url做编码,否则在做json的key会有问题
if (cacheImgList[encodeUrl]) {
item.image = cacheImgList[encodeUrl];
} else {
downloadFileList.push(item.image);
}
});
_this.downloadImg(saveFileList, downloadFileList);
},
/**
* fileList 所有需要保存的图片,包括已经保存的图片
* downloadFileList 需要下载的图片列表
*/
downloadImg(fileList, downloadFileList) {
const fs = wx.getFileSystemManager();
let cacheImgList = wx.getStorageSync('cacheImgList') || {};
for (let key in cacheImgList) {
if (!fileList.includes(decodeURIComponent(key))) {
fs.removeSavedFile({ filePath: cacheImgList[key] });
delete cacheImgList[key];
}
}
wx.setStorageSync('cacheImgList', cacheImgList);
downloadFileList.forEach(url => {
wx.downloadFile({
url,
success(res) {
if (res.statusCode === 200) {
fs.saveFile({
tempFilePath: res.tempFilePath,
success(res) {
let cacheImgList = wx.getStorageSync('cacheImgList') || {};
cacheImgList[encodeURIComponent(url)] = res.savedFilePath;
wx.setStorageSync('cacheImgList', cacheImgList)
}
})
}
}
});
})
},
注意事项
- 该方法只有10m的空间,要合理利用和回收,否则空间超过限制后,比加载慢还难过。
- 这里存在localstorage的数据是个Object,key是图片原地址,value是本地缓存的地址。也可以使用Array存储,需要保存key和value两个值