知識(shí)
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們?cè)谧非笃湟曈X表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營銷的便利,運(yùn)營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏?jí)提供便捷的支持!
您當(dāng)前位置>首頁 » 新聞資訊 » 小程序相關(guān) >
小程序性能優(yōu)化——文件的本地存儲(chǔ)10M優(yōu)化算法
發(fā)表時(shí)間:2021-1-6
發(fā)布人:葵宇科技
瀏覽次數(shù):71
小程序文件的本地存儲(chǔ)優(yōu)化
優(yōu)化原因!
眾所周知,微信將小程序的本地文件存儲(chǔ)空間限制為10M,導(dǎo)致我們?cè)谡{(diào)用wx.saveFile()接口存儲(chǔ)臨時(shí)文件時(shí),存著存著,就超過10M了。那該怎么辦呢?
肯定是要寫一套算法,避免超過10M啦!
算法來源 ~
之前博主在做Android的時(shí)候,了解過LruCache類。它是Android提供的一個(gè)緩存類,當(dāng)緩存空間被占滿時(shí),會(huì)去移除最不經(jīng)常訪問的數(shù)據(jù),從而保證新數(shù)據(jù)的正常插入。這就是小程序的文件存儲(chǔ)算法的思想來源。
當(dāng)然,LruCache中是使用LinkedHashMap來管理緩存數(shù)據(jù)的,這個(gè)LinkedHashMap可厲害了,它已經(jīng)實(shí)現(xiàn)了按照訪問順序的存儲(chǔ),這就可以讓我們?cè)谙薅ǖ目臻g滿了的時(shí)候,方便的移除最不常訪問的數(shù)據(jù)。這就是LruCache實(shí)現(xiàn)的思路。
在小程序里,我們的文件是存儲(chǔ)在磁盤中的,可以調(diào)用wx.getSavedFileList()來獲取所有文件在存儲(chǔ)時(shí)保存的信息。微信官方指出,可以獲取到三項(xiàng)內(nèi)容。
這是我們僅能獲取到的文件信息了,里面并沒有訪問時(shí)間的記錄。所以針對(duì)這僅有的幾條信息,我們不能將LruCache的思想硬搬過來,需要有所修改。
針對(duì)小程序的文件存儲(chǔ)算法
要把大象裝冰箱,總共分幾步?!在寫算法之前,我們先要根據(jù)現(xiàn)有資源,因地制宜的制定可行的方案。
- 目前可獲取到的資源:
filePath,createTime,size
。 - 要指定一個(gè)本地可存儲(chǔ)的最大值MAX_SIZE。
那么,在存儲(chǔ)一個(gè)臨時(shí)文件時(shí),我制定了下面的算法
移除最舊文件算法
這個(gè)算法在資源方面只會(huì)用到上面提到的filePath,createTime,size
。
我認(rèn)為在用戶保存文件時(shí),如果空間已經(jīng)滿了,那么最舊的文件是或許是需要被移除的。所以可以依照createTime來移除最舊的文件。
算法核心思想就這么幾點(diǎn):
- 先獲取要保存的臨時(shí)文件的大小信息
tempFileSize
。 - 然后移除本地文件,直到剩余空間大于
tempFileSize
。 - 最后存入文件,返回本地文件路徑。
以下是代碼
const MAX_SIZE = 10400000;
let wholeSize = 0;
setTimeout(() => {
wx.getSavedFileList({
success: savedFileInfo => {
let {fileList} = savedFileInfo;
!!fileList && fileList.forEach(item => {
wholeSize += item.size;
});
}
});
});
function saveFileRule(tempFilePath, cbOk, cbError) {
wx.getFileInfo({
filePath: tempFilePath,
success: tempFailInfo => {
let tempFileSize = tempFailInfo.size;
// console.log('本地臨時(shí)文件大小', tempFileSize);
if (tempFileSize > MAX_SIZE) {
typeof cbError === "function" && cbError('文件過大');
return;
}
wx.getSavedFileList({
success: savedFileInfo => {
let {fileList} = savedFileInfo;
if (!fileList) {
typeof cbError === "function" && cbError('獲取到的fileList為空,請(qǐng)檢查你的wx.getSavedFileList()函數(shù)的success返回值');
return;
}
//這里計(jì)算需要移除的文件大小
let sizeNeedRemove = wholeSize + tempFileSize - MAX_SIZE;
if (sizeNeedRemove >= 0) {
//按時(shí)間戳排序,方便后續(xù)移除文件
fileList.sort(function (item1, item2) {
return item1.createTime - item2.createTime;
});
let sizeCount = 0;
for (let i = 0, len = fileList.length; i < len; i++) {
if ((sizeCount += fileList[i].size) >= sizeNeedRemove) {
for (let j = 0; j < i; j++) {
wx.removeSavedFile({
filePath: fileList[j].filePath,
success: function () {
wholeSize -= fileList[j].size;
}
});
}
break;
}
}
}
//存儲(chǔ)文件
wx.saveFile({
tempFilePath: tempFilePath,
success: res => {
wholeSize += tempFileSize;
typeof cbOk === "function" && cbOk(res.savedFilePath);
},
fail: cbError
});
},
fail: cbError
});
}
});
}
module.exports = {
saveFileRule
};
在需要移除本地文件時(shí),我是先將fileList按時(shí)間戳大小正向排序,這樣的話,最舊的文件信息會(huì)排在第一位,其余的依次排列。這時(shí)只要從fileList的第一個(gè)元素開始移除文件就可以了,直到剩余空間可以存入新文件為止。
下面這段代碼會(huì)在小程序冷啟動(dòng)時(shí)執(zhí)行,我在這段代碼中進(jìn)行了優(yōu)化。
setTimeout(() => {
wx.getSavedFileList({
success: savedFileInfo => {
let {fileList} = savedFileInfo;
!!fileList && fileList.forEach(item => {
wholeSize += item.size;
});
}
});
});
因?yàn)閖s單線程原因,setTimeout
會(huì)讓里面的代碼在主線程跑完后再執(zhí)行,避免小程序冷啟動(dòng)時(shí)在這上面耗時(shí)。并且對(duì)于本地文件總大小的計(jì)算,遍歷這一次就可以了,以后在執(zhí)行saveFileRule
時(shí),進(jìn)行簡(jiǎn)單的加減就可以了。
相關(guān)案例查看更多
相關(guān)閱讀
- 網(wǎng)站建設(shè)電話
- 排名
- 汽車回收管理
- 網(wǎng)站開發(fā)公司哪家好
- 搜索引擎優(yōu)化
- python開發(fā)小程序
- 昆明做網(wǎng)站
- 云南軟件公司
- php網(wǎng)站
- 網(wǎng)站建設(shè)首頁
- 手機(jī)網(wǎng)站建設(shè)
- 小程序開發(fā)排名前十名
- 云南網(wǎng)站建設(shè)特性
- 網(wǎng)頁制作
- 昆明小程序代建
- 昆明網(wǎng)站設(shè)計(jì)
- 云南網(wǎng)站建設(shè)列表網(wǎng)
- 做網(wǎng)站
- 云南網(wǎng)站建設(shè)公司哪家好
- 人口普查小程序
- 小程序的開發(fā)公司
- 云南網(wǎng)站建設(shè)百度
- 云南小程序哪家好
- 云南小程序開發(fā)公司
- 網(wǎng)站開發(fā)
- 云南網(wǎng)站建設(shè) 網(wǎng)絡(luò)服務(wù)
- 網(wǎng)站建設(shè)制作
- 云南網(wǎng)頁制作
- 云南網(wǎng)絡(luò)公司
- 報(bào)廢車回收管理軟件