Кэширование запросов является важным аспектом оптимизации производительности фронтенд-приложений. Во Vue.js оно позволяет уменьшить количество повторных HTTP-запросов к серверу, ускорить рендеринг компонентов и снизить нагрузку на сеть.
Во Vue.js все данные компонентов являются реактивными. Это означает,
что любые изменения состояния автоматически отражаются в DOM. Для
кэширования запросов реактивные свойства часто используются совместно с
объектами ref или reactive.
import { ref } from 'vue';
export default {
setup() {
const dataCache = ref(null);
const loading = ref(false);
const fetchData = async () => {
if (dataCache.value) return dataCache.value; // Возврат из кэша
loading.value = true;
const response = await fetch('https://api.example.com/data');
dataCache.value = await response.json();
loading.value = false;
return dataCache.value;
}
return { dataCache, loading, fetchData };
}
}
В этом примере данные сохраняются в dataCache после
первого запроса. Повторные вызовы fetchData используют
кэшированное значение, если оно доступно.
Vuex позволяет хранить состояние приложения централизованно. Кэширование запросов на уровне Vuex особенно полезно для данных, используемых в нескольких компонентах.
// store.js
import { createStore } from 'vuex';
export const store = createStore({
state() {
return {
itemsCache: {}
}
},
mutations: {
setCache(state, { key, data }) {
state.itemsCache[key] = data;
}
},
actions: {
async fetchItems({ state, commit }, key) {
if (state.itemsCache[key]) return state.itemsCache[key];
const response = await fetch(`https://api.example.com/items/${key}`);
const data = await response.json();
commit('setCache', { key, data });
return data;
}
}
});
Использование Vuex для кэширования позволяет обращаться к одним и тем же данным из разных компонентов без повторных сетевых запросов.
Для более сложного кэширования можно использовать библиотеки, такие
как Axios с интерцепторами или
SWR/vue-query. Пример с Axios:
import axios from 'axios';
const cache = {};
axios.interceptors.request.use(config => {
const key = config.url;
if (cache[key]) {
config.adapter = () => {
return Promise.resolve({
data: cache[key],
status: 200,
statusText: 'OK',
headers: {},
config
});
}
}
return config;
});
axios.interceptors.response.use(response => {
cache[response.config.url] = response.data;
return response;
});
Такой подход позволяет автоматически кэшировать все запросы и возвращать данные из кэша без изменения логики компонентов.
Для долговременного кэширования можно использовать
localStorage или IndexedDB. Это актуально для
данных, которые должны сохраняться между перезагрузками страницы:
const cacheKey = 'usersData';
async function fetchUsers() {
const cached = localStorage.getItem(cacheKey);
if (cached) return JSON.parse(cached);
const response = await fetch('https://api.example.com/users');
const data = await response.json();
localStorage.setItem(cacheKey, JSON.stringify(data));
return data;
}
Использование локального хранилища позволяет быстро загружать данные при последующих визитах без необходимости обращения к серверу.
Выбор стратегии зависит от характера данных. Для редко меняющейся информации предпочтителен cache-first, а для динамических данных — stale-while-revalidate.
Важно поддерживать актуальность кэша. В Vue.js это достигается с помощью реактивных свойств:
import { reactive } from 'vue';
const state = reactive({
postsCache: {}
});
async function fetchPost(id) {
if (!state.postsCache[id]) {
const response = await fetch(`https://api.example.com/posts/${id}`);
state.postsCache[id] = await response.json();
}
return state.postsCache[id];
}
Любые изменения state.postsCache автоматически обновляют
компоненты, которые используют эти данные.
При использовании кэша необходимо контролировать размер хранимых данных. Для этого можно реализовать TTL (time-to-live) или ограничение на количество элементов:
const cache = {};
const TTL = 60000; // 1 минута
function setCache(key, data) {
cache[key] = { data, timestamp: Date.now() };
}
function getCache(key) {
const cached = cache[key];
if (!cached) return null;
if (Date.now() - cached.timestamp > TTL) {
delete cache[key];
return null;
}
return cached.data;
}
Такой подход предотвращает накопление устаревших данных и снижает нагрузку на память.
Кэширование запросов во Vue.js сочетает реактивность, централизованное состояние и возможности внешних библиотек. Применение стратегий кэширования, контроль времени жизни данных и интеграция с Vuex или Axios позволяют создавать быстрые и отзывчивые интерфейсы, минимизируя количество сетевых обращений.