欧美三级国产三级日韩三级_亚洲熟妇丰满大屁股熟妇_欧美亚洲成人一区二区三区_国产精品久久久久久模特

小程序性能優(yōu)化——文件的本地存儲(chǔ)10M優(yōu)化算法 - 新聞資訊 - 云南小程序開發(fā)|云南軟件開發(fā)|云南網(wǎng)站建設(shè)-昆明葵宇信息科技有限公司

159-8711-8523

云南網(wǎng)建設(shè)/小程序開發(fā)/軟件開發(fā)

知識(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):

  1. 先獲取要保存的臨時(shí)文件的大小信息tempFileSize。
  2. 然后移除本地文件,直到剩余空間大于tempFileSize
  3. 最后存入文件,返回本地文件路徑。

以下是代碼

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)案例查看更多