Кэширование запросов является важной техникой для оптимизации производительности веб-приложений, снижая нагрузку на сервер и ускоряя отклик пользовательского интерфейса. Riot.js, как легковесный компонентный фреймворк, предоставляет гибкие возможности для реализации кэширования на уровне компонентов или глобально.
Кэширование на стороне клиента
В простейшей реализации данные сохраняются в памяти браузера на время жизни компонента или сессии. Это позволяет повторно использовать результаты асинхронных запросов без повторного обращения к серверу.
import { component } from 'riot'
const cache = {}
export default component('user-list', {
async onMounted() {
if (!cache.users) {
const response = await fetch('/api/users')
cache.users = await response.json()
}
this.state.users = cache.users
}
})
Ключевым моментом является единственное место хранения кэша, доступное всем компонентам, которым нужны одинаковые данные. Это может быть отдельный модуль или глобальный объект.
Кэширование с использованием LocalStorage и SessionStorage
Для долговременного хранения кэша между перезагрузками страницы
удобно использовать localStorage или
sessionStorage. Данные сериализуются в JSON и извлекаются
при инициализации компонента:
const cacheKey = 'usersCache'
export default component('user-list', {
async onMounted() {
const cachedData = localStorage.getItem(cacheKey)
if (cachedData) {
this.state.users = JSON.parse(cachedData)
} else {
const response = await fetch('/api/users')
const users = await response.json()
localStorage.setItem(cacheKey, JSON.stringify(users))
this.state.users = users
}
}
})
Такой подход эффективен для редко меняющихся данных, например, справочников или настроек.
Инвалидизация кэша
Любой кэш требует механизма обновления данных, чтобы информация не устаревала. В Riot.js это можно реализовать с помощью таймеров или событий:
const cache = {}
const CACHE_DURATION = 5 * 60 * 1000 // 5 минут
export default component('user-list', {
async onMounted() {
const now = Date.now()
if (!cache.users || now - cache.timestamp > CACHE_DURATION) {
const response = await fetch('/api/users')
cache.users = await response.json()
cache.timestamp = now
}
this.state.users = cache.users
}
})
Здесь используется метка времени для автоматического обновления данных после заданного периода.
Riot.js позволяет создавать локальные кэши внутри компонентов, что особенно удобно для повторного рендера и предотвращения лишних запросов при навигации:
export default component('post-list', {
state: { posts: [] },
async onMounted() {
if (!this.cache) this.cache = {}
if (!this.cache.posts) {
const response = await fetch('/api/posts')
this.cache.posts = await response.json()
}
this.state.posts = this.cache.posts
}
})
Особенность локального кэша — его жизненный цикл привязан к компоненту. После удаления компонента данные исчезают, что иногда предпочтительнее глобального хранения.
Для крупных приложений рекомендуется вынести кэширование в отдельные сервисы, которые инкапсулируют логику запросов и хранения данных:
// cacheService.js
const cache = {}
export async function fetchWithCache(url) {
if (cache[url]) return cache[url]
const response = await fetch(url)
const data = await response.json()
cache[url] = data
return data
}
Использование в компоненте:
import { fetchWithCache } from './cacheService'
export default component('user-list', {
async onMounted() {
this.state.users = await fetchWithCache('/api/users')
}
})
Такой подход обеспечивает централизованное управление кэшированием, легко добавляются механизмы инвалидизации и логирования.
this.state или
this.update() для корректного рендера.async/await и обрабатывать
ошибки.localStorage или
IndexedDB.Кэширование запросов в Riot.js повышает производительность приложения, снижает нагрузку на сервер и делает интерфейс более отзывчивым. Правильная архитектура кэша позволяет избежать дублирования запросов и поддерживать актуальность данных при минимальных усилиях.