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