小程序-圖片/文件本地緩存,減少CDN流量消耗

寫在前面

小程序網絡圖片讀取:

  1. 在讀取OSS圖片CDN分發時流量大量消耗,導致資金費用增加。
  2. 網絡圖片比較大時,圖片加載緩慢。

爲了儘量減少上面兩個問題,所以對已讀的圖片進行緩存處理,減少多次訪問不必要的流量消耗。

小程序的文件系統

文件主要分爲兩大類:

  • 代碼包文件:代碼包文件指的是在項目目錄中添加的文件。
  • 本地文件:通過調用接口本地產生,或通過網絡下載下來,存儲到本地的文件。

其中本地文件又分爲三種:

  1. 本地臨時文件:臨時產生,隨時會被回收的文件。不限制存儲大小。
  2. 本地緩存文件:小程序通過接口把本地臨時文件緩存後產生的文件,不能自定義目錄和文件名。跟本地用戶文件共計,普通小程序最多可存儲 10MB,遊戲類目的小程序最多可存儲 50MB。
  3. 本地用戶文件:小程序通過接口把本地臨時文件緩存後產生的文件,允許自定義目錄和文件名。跟本地緩存文件共計,普通小程序最多可存儲 10MB,遊戲類目的小程序最多可存儲 50MB。

而我們要使用的文件緩存方式就是 本地臨時文件

實現原理

圖片緩存流程:

  1. 將要圖片/文件通過wx.downloadFile(Object object)下載到本地,成爲本地臨時文件。
  2. 使用小程序的Storage記錄網絡地址本地地址,做映射。
  3. 使用時,在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
}

寫在後面

本文參照博客

  • https://juejin.im/post/5b42d3ede51d4519277b6ce3

(幽蟄 寫於 2020.06.10)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章