小程式 LRU 儲存設計案例

2022-09-24 01:54:08 字數 2406 閱讀 2384

為了解決小程式生成分享到朋友圈的問題,我們開啟了畫家計畫--- 乙個小程式生成庫。該計畫已開源,可移步:github.com/kujiale-mob…。 大家知道 canvas 的繪製有很多很蛋疼的坑,其中乙個是它的 drawimage 方法,該方法在 ide 中可以直接設定為網路的 url 進行繪製,但在真機上無法這樣做。有這個坑後,我們就需要先把通過 download **到本地後,才能進行繪製。所以你的小程式中,如果有頻繁繪製一些的需求,而又需要用到網路素材,這就導致每次繪製都要重新**素材,產生很大的繪製效能問題。

小程式本身是未提供檔案 lru 之類的快取機制的。為了讓我們的畫家計畫生成的更快,我們自己開發了的小程式檔案進行 lru 儲存的相關**。這樣我們就無需重複**可能會頻繁使用到的繪圖素材,大大增加了繪圖速度。

小程式的快取分為資料快取,和檔案快取兩部分。而檔案快取又分為臨時檔案快取,和本地檔案儲存。其中本地檔案儲存的大小限制為 10m。

我們可以使用小程式提供的一套非同步和同步的方法來增刪查結構化資料。同乙個微信使用者,同乙個小程式的儲存上限為 10mb。如果空間不足時會在小程式級別進行 lru,也就是不經常使用的小程式的資料快取區域會被全部清空。

詳細見微信官方文件:

注:資料快取區在體驗版、開發版、和線上版都共用一套,並不會隔離。我們在呼叫 wx.downloadfile 或者 wx.chooseimage 等獲取檔案或的方式成功後,我們會得到這個檔案或的臨時儲存路徑。文件上寫的是臨時路徑的生命週期是在本次小程式啟動期間內。

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

我們在獲得臨時檔案後,可以通過呼叫介面 wx.s**efile 把臨時檔案儲存到本地空間中,本地空間儲存限制為 10m。如果儲存滿了後,後面的檔案就無法儲存成功了,會報超出最大儲存上限的錯誤。

而我們現在需要做的就是在這個本地儲存空間上,開闢乙個空間,作為我們**檔案的儲存空間,因空間有限,所以我們需要對這塊空間進行 lru 管理。

有關本地儲存相關的介面可看以下文件:

注:把臨時檔案通過呼叫 s**efile 成功後,這個臨時檔案路徑就無效了。切記切記。小程式端的本地儲存有 10m 限制,但卻無 lru,現在我們需要結合上面提到的小程式三種儲存方式來實現一套小程式檔案**的 lru 機制。

....

'totalsize': // 所有儲存檔案的當前總大小

}複製**

其中我們用**的 url 作為 key。 以上資料結構會存在在資料快取區(後續我們會把這個區域稱為 storage 區),並且在**器構建之時會從 storage 中讀取到記憶體中。以後的檔案操作,也會實時同步到 storage 中記錄的檔案資訊。

你可以理解為,storage 中儲存了檔案的基本資訊,而 path 就相當於指向這個實際檔案的指標。

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

第一種,storage 的某檔案資訊被刪除了,但檔案本身卻因為出現神奇錯誤而未被刪除。另外檔案新增成功了,但 storage 中卻未新增成功也屬於此情況。

第二種,storage 中檔案資訊刪除失敗,但是檔案卻被刪除了。

以上兩種性質不同,所以也需要區別對待。針對第一種會導致檔案的儲存空間和 storage 中記錄的檔案資訊不一致,也即出現了游離的檔案(未被 storage 跟蹤)。

而第二種,相當於存在了空指標,此種情況是絕對需要避免的,因為這會導致你在拿出乙個不存在的檔案使用。會直接導致嚴重bug。

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

而針對第一種游離檔案的情況。我們這邊會在 s**efile 的時機進行兜底處理。如果存在了游離檔案,最終會導致我們空間總大小計算不一致,這可能最終會導致,我們外部邏輯認為可以儲存,但實際儲存空間已經滿了,這樣就會導致 s**efile 報錯,在 s**efile 出錯後,不管啥原因,我們都把涉及到本策略儲存相關的內容全部清空掉,重新來過。因為我們一直有 tempfilepath 兜底,所以即使這種情況出現,也不會影響使用者正常使用。只是會影響一點使用者體驗(畢竟一下子沒有以前的快取了)。

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

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

目前這一套 lru 的檔案儲存機制已經在我們開源的 painter 庫中使用,如有興趣請移步:github.com/kujiale-mob…。

小程式雲開發案例

最新更新的微信 web 開發者工具支援了雲開發 和之前免費提供的自動部署的測試環境不同,這次是生產和開發都不需要一 立的伺服器了 取而代之的是雲檔案,雲函式和雲資料庫 和 bmob 雲有點像 更新到最新的微信 web 開發者工具就行了 新建專案,使用雲開發快速啟動專案模板 必須是自己的 appid,...

小程式 本地儲存

通過collected來判斷!1 var newsdata require data newsdata.js 23 page 1112 13 生命週期函式 監聽頁面載入 14 15 onload function options 21 第一次進入的適合判斷是否存在本地儲存以及是否收藏 22var n...

小程式 塗鴉畫筆 案例 集福

不同的專案總是要求不同的需求 在下面的 中,我自碼了畫福的canvas 及橡皮檫的 下面的圖中也需實現背景圖的點選切換取,點選畫圖完畢按鈕,就實現了內容的提交 橡皮檫按鈕 js var canvasc 宣告乙個全域性變數,用於橡皮檫 page startx 0 儲存x座標軸變數 starty 0 儲...