uni-app緩存器的封裝

在前端開發應用程序中,性能一直都是被你們所重視的一點,然而判斷一個應用程序的性能最直觀的就是看頁面打開的速度。其中提升頁頁面反應速度的一個方式就是使用緩存。一個優秀的緩存策略能夠縮短頁面請求資源的距離,減小延遲,而且因爲緩存文件能夠重複利用,還能夠減小帶寬,下降網絡負荷。html

前端經常使用緩存技術在這裏我就再也不描述,下面基於Storage對其進行加強,採用Map 基本相同的api。前端

閱讀如下內容時遇到不懂的,請先科普阮一峯老師的ECMAScript 6 入門html5

下面是基本代碼,會在此基礎上進行加強

class MinCache {
  // 將數據存儲在本地緩存中指定的 name 中
  set (name, data) {
    try {
      uni.setStorageSync(name, data)
    } catch (e) {
      console.log(e)
    }
  }
  // 從本地緩存中獲取指定 name 對應的內容
  get (name) {
    let data
    try {
      data = uni.getStorageSync(name)
    } catch (e) {
      console.log(e)
    }
    return data
  }
  // 從本地緩存中移除指定 key
  delete (name) {
    try {
      uni.removeStorageSync(name)
    } catch (e) {
      console.log(e)
    }
  }
  // 返回一個布爾值,表示 name 是否在本地緩存之中
  has (name) {
    const value
    try {
      const res = uni.getStorageInfoSync()
      value = res.keys.includes(name)
    } catch (e) {
      console.log(e)
    }
    return value
  }
  // 清理本地數據緩存
  clear () {
    try {
      uni.clearStorageSync()
    } catch (e) {
      console.log(e)
    }
  }
}

export default MinCache複製代碼

咱們知道緩存每每是有危害的,那麼咱們最好規定個時間來去除數據。

class CacheCell {
  constructor (data, timeout) {
    this.data = data
    // 設置超時時間,單位秒
    this.timeout = timeout
    // 對象建立時候的時間
    this.createTime = Date.now()
  }
}複製代碼
set (name, data, timeout = 1200) {
    const cachecell = new CacheCell(data, timeout)
    try {
      uni.setStorageSync(name, cachecell)
    } catch (e) {
      console.log(e)
    }
  }
  get (name) {
    let data = null
    try {
      data = uni.getStorageSync(name)
      if (!data) return null
      const currentTime = Date.now()
      const overTime = (currentTime - data.createTime) / 1000
      if (overTime > data.timeout) {
        try {
          uni.removeStorageSync(name)
          data = null
        } catch (e) {
          console.log(e)
        }
      }
    } catch (e) {
      console.log(e)
    }
    return data
  }複製代碼

使用了過時時間進行緩存的方式,已經能夠知足絕大部分的業務場景。git

uni-app的Storage在不一樣端的實現不一樣:es6

  • H5端爲localStorage,瀏覽器限制5M大小,是緩存概念,可能會被清理github

  • App端爲原生的plus.storage,無大小限制,不是緩存,持久化web

  • 各個小程序端爲其自帶的storage api,數據存儲生命週期跟小程序自己一致,即除用戶主動刪除或超過必定時間被自動清理,不然數據都一直可用。sql

  • 微信小程序單個 key 容許存儲的最大數據長度爲 1MB,全部數據存儲上限爲 10MB。小程序

  • 支付寶小程序單條數據轉換成字符串後,字符串長度最大200*1024。同一個支付寶用戶,同一個小程序緩存總上限爲10MB。微信小程序

  • 百度、頭條小程序文檔未說明大小限制

除此以外,H5端還支持websql、indexedDB、sessionStorage;App端還支持SQLiteIO文件等本地存儲方案。

咱們能夠看出來Storage在一些端中是有大小限制的,其實咱們的數據只是想要緩存,不必定要持久化。

也就是說在應用程序生命週期內使用就行,並且直接操做Storage也不是很好。

咱們知道ES6中有Map能夠作緩存

下面代碼時基於Map封裝的

let cacheMap =  new Map()
let instance = null
let timeoutDefault = 1200

function isTimeout (name) {
  const data = cacheMap.get(name)
  if (!data) return true
  if (data.timeout === 0) return false
  const currentTime = Date.now()
  const overTime = (currentTime - data.createTime) / 1000
  if (overTime > data.timeout) {
    cacheMap.delete(name)
    return true
  }
  return false
}

class CacheCell {
  constructor (data, timeout) {
    this.data = data
    this.timeout = timeout
    this.createTime = Date.now()
  }
}

class Cache {
  set (name, data, timeout = timeoutDefault) {
    const cachecell = new CacheCell(data, timeout)
    return cacheMap.set(name, cachecell)
  }
  get (name) {
    return isTimeout(name) ? null : cacheMap.get(name).data
  }
  delete (name) {
    return cacheMap.delete(name)
  }
  has (name) {
    return !isTimeout(name)
  }
  clear () {
    return cacheMap.clear()
  }
  setTimeoutDefault (num) {
    if (timeoutDefault === 1200) {
      return timeoutDefault = num
    }
    throw Error('緩存器只能設置一次默認過時時間')
  }
}

class ProxyCache {
  constructor () {
    return instance || (instance = new Cache())
  }
}

export default ProxyCache複製代碼

對Storage和Map封裝的緩存進行整合

咱們來分析一下

  • Storage和Map共用一套api

    • 在命名上解決如下劃線_開頭命名的緩存到Storage,而且Map也有副本

  • 儘可能不操做Storage(讀取速度慢)

    • 那就必須在應用程序初始化的時候把Storage加載進Map

  • 像Vue插件同樣使用

let cacheMap =  new Map()
let timeoutDefault = 1200

function isTimeout (name) {
  const data = cacheMap.get(name)
  if (!data) return true
  if (data.timeout === 0) return false 
  const currentTime = Date.now()
  const overTime = (currentTime - data.createTime) / 1000
  if (overTime > data.timeout) {
    cacheMap.delete(name)
    if (name.startsWith('_')) {
      try {
        uni.removeStorageSync(name)
      } catch (e) {
        console.log(e)
      }
    }
    return true
  }
  return false
}

class CacheCell {
  constructor (data, timeout) {
    this.data = data
    this.timeout = timeout
    this.createTime = Date.now()
  }
}

class MinCache {
  constructor (timeout) {
    try {
      const res = uni.getStorageInfoSync()
      res.keys.forEach(name => {
        try {
          const value = uni.getStorageSync(name)
          cacheMap.set(name, value)
        } catch (e) {
          console.log(e)
        }
      })
    } catch (e) {
      console.log(e)
    }
    timeoutDefault = timeout
  }
  set (name, data, timeout = timeoutDefault) {
    const cachecell = new CacheCell(data, timeout)
    let cache = null
    if (name.startsWith('_')) {
      try {
        uni.setStorageSync(name, cachecell)
        cache = cacheMap.set(name, cachecell)
      } catch (e) {
        console.log(e)
      }
    } else {
      cache = cacheMap.set(name, cachecell)
    }
    return cache
  }
  get (name) {
    return isTimeout(name) ? null : cacheMap.get(name).data
  }
  delete (name) {
    let value = false
    if (name.startsWith('_')) {
      try {
        uni.removeStorageSync(name)
        value = cacheMap.delete(name)
      } catch (e) {
        console.log(e)
      }
    } else {
      value = cacheMap.delete(name)
    }
    return value
  }
  has (name) {
    return !isTimeout(name)
  }
  clear () {
    let value = false
    try {
      uni.clearStorageSync()
      cacheMap.clear()
      value = true
    } catch (e) {
      console.log(e)
    }
    return value
  }
}

MinCache.install = function (Vue, {timeout = 1200} = {}) {
  Vue.prototype.$cache = new MinCache(timeout)
}

export default MinCache複製代碼

使用方法

name如下劃線_開頭命名的緩存到Storage,而且Map也有副本

事件名 參數 說明 返回值
set name緩存的key,data緩存的數據,timeout(必須數字單位s)緩存時間,默認緩存1200s, timeout設置爲0表示永久緩存 設置緩存數據 Map集合
get name緩存的key 獲取數據(緩存過時將返回null) 返回緩存的數據data
has name緩存的key 檢查值 true/false
delete name緩存的key 刪除數據 true/false
clear - 清空Storage和Map緩存數據 true/false
// 註冊緩存器
Vue.use(MinCache)
// 設置默認緩存時間
// Vue.use(MinCache, {timeout: 600})複製代碼
// 'name'不是如下劃線開頭的表示會緩存到Map中,在程序生命週期內有而且在有效時間內有效
this.$cache.set('name', 'MinCache')

// 過時時間設置爲0表示不會過時
// 注意:'test'並非如下劃線命名錶示在程序生命週期永久緩存
this.$cache.set('test', 'testdemo', 0)

// 過時時間設置爲0表示不會過時
// 注意:'_imgURL'是如下劃線命名錶示永久緩存到Storage
this.$cache.set('_imgURL', 'data', 0)複製代碼
// 獲取緩存的數據
this.imgURL = this.$cache.get('_imgURL')
this.name = this.$cache.get('name')
this.test = this.$cache.get('test')複製代碼

具體使用方法能夠參考github

uni-app路由的封裝

相關文章
相關標籤/搜索