項目中資源緩存機制實踐(靜態資源和本地數據緩存)

網絡資源的緩存

核心方案javascript

  1. HTML文件 no-cache
  2. js,css文件 時間戳/哈希/版本號,長緩存
  3. 圖片資源 長緩存,更新時使用新連接地址
1. 先後端未分離,且未引入構建工具的項目

方案:每次上線時,維護一個版本記錄,由後端給每一個頁面上提供當前的版本號,前端在引用js和css時將版本號放在資源的query參數中。css

例如:前端

原先:
<script src="/static/js/utils.js"></script>
<script src="/static/js/index.js"></script>

改後:
// 每次發版維護的版本號
const version = '2.2';
// 動態填寫js引用
document.write("<script type='text/javascript' src=./utils.js?version="+ version + "><\/script>");

2. 使用構建工具的項目

方案:使用webpack和grunt之類的工具,每次發版時使用工具使用hash更新靜態資源的版本java

例如:webpack

<script src="/static/js/0.2e29befc85b7d79378f4.js"></script>

本地緩存的管理

cookie、localStorage、sessionStorage、IndexDB、App cache、service worker
使用本地存儲的注意點:
  1. 使用要有節制,同一個域名下共享localstorage空間,若是一個域名下的業務很是多,極可能存儲量超過限制。像咱們的不一樣業務域名時projectA.XXX.com, projectB.XXX.com 而不是www.XXX.com/projectA, www.XXX.com/projectB。使用子域名能夠分離storage空間,互不干擾。
  2. 使用要有降級方案,不能徹底依賴storge完成業務功能。若是storage讀寫失敗,使用備用方案。
  3. 使用時要有版本管理。storage中儲存的key也要有版本管理,便於迭代時避免不一樣版本之間數據衝突。 V1.0.0_XXXX

下面寫了一個用於本地存取的工具,項目中使用時能夠將工具綁定到全局空間中使用。例如在Vue生態中,能夠結合Vux一塊兒使用web

const namespace = 'matchu'
const version = '2.2'

function setLocal(key, value, priority) {
  try {
    // 設置的優先級不合法,爲非數字時,使用最低優先級0
    priority = /^[0-9]\d*$/.test(priority) ? priority : 0
    localStorage.setItem(`${namespace}_V:${version}_P:${priority}`, JSON.stringify(value))
    return getLocal(key)
  } catch (err) {
    if (/exceeded the quota/.test(err)) {
      // 存儲超出限額, 清除低優先級的數據
      clearLowPriorityLocal(priority)
    }
  }
}

function getLocal(key, value) {
  try {
    let result = localStorage.getItem(key)
    // 讀取成功當即返回值
    // 讀取失敗則嘗試先存儲數據,再返回已存入的數據
    result = result ? JSON.parse(result) : setLocal(key, value)
    return result
  } catch (err) {
    // 讀取失敗
    console.log(err)
  }
}

// 刪除指定key數據
function removeLocal(key) {
  try {
    localStorage.removeItem(key)
  } catch (err) {
    // 清除全部數據失敗
    console.log(err)
  }
}

// 刪除全部數據
function clearAllLocal() {
  try {
    localStorage.clear()
  } catch (err) {
    // 清除全部數據失敗
    console.log(err)
  }
}

// 正則匹配刪除當前命名空間且非當前版本的數據
function clearOtherVersionLocal() {
  try {
    const reg = new RegExp(`^${namespace}_V:(?!${version})`)
    Object.keys(localStorage).forEach(key => {
      if (reg.test(key)) {
        removeLocal(key)
      }
    })
  } catch (err) {
    console.log(err)
  }
}

// 正則匹配刪除低於當前優先級的數據
function clearLowPriorityLocal(priority) {
  try {
    const reg = new RegExp(`[^${namespace}_V:${version}_P:]`)
    Object.keys(localStorage).forEach(key => {
      const index = key.match(reg).index
      if (index && key.slice(index) < priority) {
        removeLocal(key)
      }
    })
  } catch (err) {
    console.log(err)
  }
}
export default {
  setLocal: setLocal, // 存storage數據
  getLocal: getLocal, // 取storage
  removeLocal: removeLocal, //刪除指定key的數據
  clearAllLocal: clearAllLocal, // 刪除所有數據
  clearOtherVersionLocal: clearOtherVersionLocal, // 清除非本次版本的數據
  clearLowPriorityLocal: clearLowPriorityLocal // 清除低於當前優先級的數據
}
相關文章
相關標籤/搜索