小程式-圖片/文件本地快取,減少CDN流量消耗
♠ 寫在前面
小程式網路圖片讀取:
- 在讀取OSS圖片CDN分發時流量大量消耗,導致資金費用增加。
- 網路圖片比較大時,圖片載入緩慢。
為了盡量減少上面兩個問題,所以對已讀的圖片進行快取處理,減少多次訪問不必要的流量消耗。
♠ 小程式的文件系統
文件主要分為兩大類:
- 程式碼包文件:程式碼包文件指的是在項目目錄中添加的文件。
- 本地文件:通過調用介面本地產生,或通過網路下載下來,存儲到本地的文件。
其中本地文件又分為三種:
- 本地臨時文件:臨時產生,隨時會被回收的文件。不限制存儲大小。
- 本地快取文件:小程式通過介面把本地臨時文件快取後產生的文件,不能自定義目錄和文件名。跟本地用戶文件共計,普通小程式最多可存儲 10MB,遊戲類目的小程式最多可存儲 50MB。
- 本地用戶文件:小程式通過介面把本地臨時文件快取後產生的文件,允許自定義目錄和文件名。跟本地快取文件共計,普通小程式最多可存儲 10MB,遊戲類目的小程式最多可存儲 50MB。
而我們要使用的文件快取方式就是 本地臨時文件 。
♠ 實現原理
圖片快取流程:
- 將要圖片/文件通過
wx.downloadFile(Object object)
下載到本地,成為本地臨時文件。 - 使用小程式的Storage記錄網路地址和本地地址,做映射。
- 使用時,在Storage讀取映射表。如果存在本地文件,並通過
FileSystemManager.accessSync(string path)
判斷文件存在,則讀取本地地址;不存在,刪除該映射。
♠ 注意
- 圖片快取只針對多次訪問的圖片,請按照實際情況調用。如果訪問一次的也做,CDN流量消耗反倒翻倍,得不償失。
- 小程式快取最大10M。為防止將快取寫滿,小程式初始化時,如果超過1000條,清空快取記錄,重新開始。
- 1000條。該數不是固定數字,請根據自己的實際情況自定。如果你本身就會往Storage放數據,請自行判斷需要多少條,不要導致其他數據無法存入,影響其他功能正常使用。
- 為什麼不用LRU最近使用刪除?沒必要。1000本身是個虛數,留存
1~2M
做其他程式碼備用,而文件非同步保存,本身會導致有好多文件無法檢測到,如果通過循環去判斷最近時間,太耗費性能,還不如進入小程式時,直接清空,從頭開始。小程式本身是輕量級的,一段時間清空一次即可。
♠ 程式碼
const fileSystem = wx.getFileSystemManager()
const getStorageImage = (web_image) => {
let webImages = wx.getStorageSync('webImages') || []
let webImage = webImages.find(y => y.web_path === web_image)
if (webImage) {
try {
fileSystem.accessSync(webImage.local_path)
return webImage.local_path
} catch(e) {
let webImageIdx = webImages.findIndex(y => y.web_path === web_image)
webImages.splice(webImageIdx, 1)
wx.setStorageSync('webImages', webImages)
}
} else {
wx.downloadFile({
url: web_image,
success (res) {
if (res.statusCode === 200) {
let filePath = res.tempFilePath
let webImageStorage = wx.getStorageSync('webImages') || []
let storage = {
web_path: web_image,
local_path: filePath,
last_time: Date.parse(new Date()),
}
webImageStorage.push(storage)
wx.setStorageSync('webImages', webImageStorage)
}
}
})
}
return web_image
}
module.exports = {
getStorageImage
}
♠ 寫在後面
本文參照部落格
//juejin.im/post/5b42d3ede51d4519277b6ce3
(幽蟄 寫於 2020.06.10)