小程序模板網(wǎng)

小程序 LRU 存儲設(shè)計

發(fā)布時間:2018-07-17 09:11 所屬欄目:小程序開發(fā)教程

為了解決小程序生成分享到朋友圈圖片的問題,我們開啟了 畫家計劃--- 一個小程序圖片生成庫。該計劃已開源,可移步: github.com/Kujiale-Mob… 。 大家知道 Canvas 的繪制有很多很蛋疼的坑,其中一個是它的 drawImage 方法,該方法在 IDE 中可以直接設(shè)置為網(wǎng)絡(luò)圖片的 url 進行繪制,但在真機上無法這樣做。有這個坑后,我們就需要先把圖片通過 download 下載到本地后,才能進行繪制。所以你的小程序中,如果有頻繁繪制一些圖片的需求,而又需要用到網(wǎng)絡(luò)圖片素材,這就導(dǎo)致每次繪制都要重新下載素材圖片,產(chǎn)生很大的繪制性能問題。

小程序本身是未提供文件 LRU 之類的緩存機制的。為了讓我們的 畫家計劃 圖片生成的更快,我們自己開發(fā)了的小程序文件進行 LRU 存儲的相關(guān)代碼。這樣我們就無需重復(fù)下載可能會頻繁使用到的繪圖素材,大大增加了繪圖速度。

介紹下小程序的緩存系統(tǒng)

小程序的緩存分為數(shù)據(jù)緩存,和文件緩存兩部分。而文件緩存又分為臨時文件緩存,和本地文件存儲。其中本地文件存儲的大小限制為 10M。

數(shù)據(jù)緩存

我們可以使用小程序提供的一套異步和同步的方法來增刪查結(jié)構(gòu)化數(shù)據(jù)。同一個微信用戶,同一個小程序的存儲上限為 10MB。如果空間不足時會在小程序級別進行 LRU,也就是不經(jīng)常使用的小程序的數(shù)據(jù)緩存區(qū)域會被全部清空。

詳細見微信官方文檔:

developers.weixin.qq.com/miniprogram…

注:數(shù)據(jù)緩存區(qū)在體驗版、開發(fā)版、和線上版都共用一套,并不會隔離。

文件臨時緩存

我們在調(diào)用 wx.downloadFile 或者 wx.chooseImage 等獲取文件或圖片的方式成功后,我們會得到這個文件或圖片的臨時存儲路徑。文檔上寫的是 臨時路徑的生命周期是在本次小程序啟動期間內(nèi) 。

不過沒有對存儲大小的限制進行說明,所以理論上不管多大文件都可以進行臨時緩存,當然如果太大肯定會造成某些神奇的錯誤吧。

本地存儲

我們在獲得臨時文件后,可以通過調(diào)用接口 wx.saveFile 把臨時文件存儲到本地空間中,本地空間存儲限制為 10M。如果存儲滿了后,后面的文件就無法存儲成功了,會報超出最大存儲上限的錯誤。

而我們現(xiàn)在需要做的就是在這個本地存儲空間上,開辟一個空間,作為我們下載文件的存儲空間,因空間有限,所以我們需要對這塊空間進行 LRU 管理。

有關(guān)本地存儲相關(guān)的接口可看以下文檔:

developers.weixin.qq.com/miniprogram…

注:把臨時文件通過調(diào)用 saveFile 成功后,這個臨時文件路徑就無效了。切記切記。

文件 LRU 存儲實現(xiàn)

小程序端的本地存儲有 10M 限制,但卻無 LRU,現(xiàn)在我們需要結(jié)合上面提到的小程序三種存儲方式來實現(xiàn)一套小程序文件下載的 LRU 機制。

數(shù)據(jù)結(jié)構(gòu)設(shè)計

{
'key': {
        'path': // 文件的存儲路徑
        'time': // 時間戳,用來記錄文件的最后訪問時間,當存儲不夠時,會選擇最遠未被訪問的文件進行刪除
        'size': // 文件大小
       }
....
'totalSize': // 所有存儲文件的當前總大小
}
復(fù)制代碼

其中我們用下載的 url 作為 key。 以上數(shù)據(jù)結(jié)構(gòu)會存在在數(shù)據(jù)緩存區(qū)(后續(xù)我們會把這個區(qū)域稱為 storage 區(qū)),并且在下載器構(gòu)建之時會從 storage 中讀取到內(nèi)存中。以后的文件操作,也會實時同步到 storage 中記錄的文件信息。

你可以理解為,storage 中存儲了文件的基本信息,而 path 就相當于指向這個實際文件的指針。

總體流程設(shè)計

容錯

因為 storage 的存儲,和文件操作都是異步的,所以有可能存在兩者不一致的情況。此處的不一致情況分兩種

第一種,storage 的某文件信息被刪除了,但文件本身卻因為出現(xiàn)神奇錯誤而未被刪除。另外文件添加成功了,但 storage 中卻未添加成功也屬于此情況。

第二種,storage 中文件信息刪除失敗,但是文件卻被刪除了。

以上兩種性質(zhì)不同,所以也需要區(qū)別對待。針對第一種會導(dǎo)致文件的存儲空間和 storage 中記錄的文件信息不一致,也即出現(xiàn)了游離的文件(未被 storage 跟蹤)。

而第二種,相當于存在了空指針,此種情況是絕對需要避免的,因為這會導(dǎo)致你在拿出一個不存在的文件使用。會直接導(dǎo)致嚴重bug。

針對以上兩種特殊情況,做了以下容錯的處理。首先我們要保證文件的刪除操作一定要在 storage 成功之后進行。這樣保證了第二種不會出錯。

而針對第一種游離文件的情況。我們這邊會在 saveFile 的時機進行兜底處理。如果存在了游離文件,最終會導(dǎo)致我們空間總大小計算不一致,這可能最終會導(dǎo)致,我們外部邏輯認為可以存儲,但實際存儲空間已經(jīng)滿了,這樣就會導(dǎo)致 saveFile 報錯,在 saveFile 出錯后,不管啥原因,我們都把涉及到本策略存儲相關(guān)的內(nèi)容全部清空掉,重新來過。因為我們一直有 tempFilePath 兜底,所以即使這種情況出現(xiàn),也不會影響用戶正常使用。只是會影響一點用戶體驗(畢竟一下子沒有以前的緩存了)。

注:之所以不像保證第二種情況的方式來保證第一種情況,是因為我覺得不需要為處理極少會出現(xiàn)的錯誤場景而去浪費性能,影響用戶體驗。只要我們做好兜底,即使這種錯誤情況萬一真的出現(xiàn),整個系統(tǒng)也不會因此出問題,還是會正常使用。

寫在后面

小程序有很多的坑。目前市面上很多小程序性能體驗并不是很好。所以為了做一款高性能的小程序,是需要我們花大量的時間去試錯,琢磨的。踩坑不止,生命不惜。



易優(yōu)小程序(企業(yè)版)+靈活api+前后代碼開源 碼云倉庫:starfork
本文地址:http://m.u-renovate.com/wxmini/doc/course/24636.html 復(fù)制鏈接 如需定制請聯(lián)系易優(yōu)客服咨詢:800182392 點擊咨詢
QQ在線咨詢
AI智能客服 ×