Инкапсуляция кеша uni-app

uni-app

Во фронтенд-разработке приложений производительность всегда была тем моментом, на который все обращали внимание, однако наиболее интуитивный способ оценить производительность приложения — посмотреть на скорость открытия страницы. Один из способов повысить скорость отклика страницы — использовать кеширование. Отличная стратегия кэширования может сократить расстояние, на котором страницы запрашивают ресурсы, уменьшить задержку, а поскольку кэшированные файлы можно использовать повторно, это также может снизить пропускную способность и нагрузку на сеть.

Я не буду здесь описывать широко используемую технологию фронтенд-кэширования, ниже будет рассмотрено ее расширение на основе Storage с использованием того же API, что и Map.

Если вы не понимаете при чтении следующего содержания, пожалуйста, сначала популяризируйте книгу учителя Руань Ифэн.Начало работы с ECMAScript 6

Ниже приведен базовый код, который будет расширен на этой основе.

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
  }

Использование срока действия для кэширования уже подходит для большинства бизнес-сценариев.

Хранилище uni-app реализовано по-разному на разных концах:

  • Сторона H5 — это localStorage, и браузер ограничивает размер до 5 МБ, что является концепцией кеша и может быть очищено.

  • Сторона приложения является родной plus.storage, без ограничений по размеру, без кеша, постоянно

  • У каждого апплета есть собственный API-интерфейс хранилища, а жизненный цикл хранения данных соответствует самому апплету, то есть, если пользователь не удалит его активно или не будет автоматически очищен через определенный период времени, данные всегда доступны.

  • Максимальная длина данных, которую можно сохранить с помощью одного ключа программы WeChat Mini, составляет 1 МБ, а верхний предел хранения всех данных составляет 10 МБ.

  • После преобразования одного фрагмента данных в апплете Alipay в строку максимальная длина строки составляет 200*1024. Для одного и того же пользователя Alipay общий лимит кеша для одного и того же апплета составляет 10 МБ.

  • В документах апплета Baidu, Toutiao не указан предельный размер

Кроме того, сторона H5 также поддерживает websql, indexedDB, sessionStorage; сторона приложения также поддерживаетSQLite,io файли другие схемы локального хранения.

Мы видим, что Storage имеет ограничение на размер в некоторых терминалах, На самом деле, наши данные хотят быть только кэшированными, не обязательно постоянными.

То есть его можно использовать в течение жизненного цикла приложения, а напрямую оперировать Storage не очень хорошо.

Мы знаем, что в ES6 есть карта, которую можно использовать для кэширования.

Следующий код основан на инкапсуляции карты.

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, а карты также имеют копии.

  • Старайтесь не использовать Хранилище (медленная скорость чтения)

    • Затем вы должны загрузить Хранилище в Карту при инициализации приложения.

  • Используйте как плагин 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

инструкции

Имя начинается с подчеркивания _ с именем кэша для хранения, а также копию карты

название события параметр иллюстрировать возвращаемое значение
set Имя кэшированного ключа, кэшированные данные данных, время ожидания (должно быть числовой единицей с) время кэширования, кэш по умолчанию — 1200 с, тайм-аут установлен на 0, чтобы указать постоянный кэш Установить данные кеша Сбор карт
get ключ кэша имени Получить данные (кэш с истекшим сроком действия вернет ноль) Возвращает кэшированные данные данных
has ключ кэша имени контрольное значение true/false
delete ключ кэша имени удалить данные true/false
clear - Пустые данные хранения и карты Cache 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

Инкапсуляция маршрутизации для одного приложения