Навіщо кешувати результати запитів?
Що означає «кешувати результати запитів»?
Кешування (від англ. cache) - це тимчасове збереження результатів запитів, щоб при повторному зверненні до тих самих даних не робити новий HTTP-запит, а використовувати вже отримані дані з пам'яті.
Приклад:
// Без кешу - щоразу новий запит
await fetch('/api/products');
// З кешем - беремо збережений результат, якщо він ще актуальний
cache.get('/api/products') ?? fetch('/api/products');Навіщо взагалі кешувати?
1. Швидкість (прискорення UI)
Кожен запит до сервера:
- займає час (навіть 100-300 мс - вже помітно);
- викликає зайві рендери, "миготіння" лоадерів;
- може бути дорогим (база, API третіх сторін).
Коли ти кешуєш результат, повторні звернення до тих самих даних:
- приходять миттєво з пам'яті (RAM);
- не показують лоадер;
- створюють відчуття «реактивного» інтерфейсу, як у нативних застосунках.
Користувач миттєво перемикається між сторінками і вкладками без повторного завантаження.
2. Зниження навантаження на сервер
Без кешу 100 користувачів, що відкрили /products, зроблять 100 запитів.
З кешем - один запит, а решта отримають дані локально.
Результат:
- менше трафіку,
- менша latency,
- дешевша інфраструктура,
- API живе довше без перевантажень.
3. Зменшення кількості станів "loading"
Коли ти переходиш між сторінками і повертаєшся назад:
- без кешу → знову "Loading...",
- з кешем → дані вже є, UI миттєво відображається.
Це різко покращує UX (сприйняття "швидкості" інтерфейсу).
4. Офлайн і "stale-while-revalidate" режими
Кеш дозволяє:
- показувати старі дані офлайн (наприклад, при втраті мережі),
- оновлювати дані у фоні, не блокуючи користувача.
Цей патерн називається Stale-While-Revalidate (SWR):
- Покажи застарілі (cached) дані миттєво.
- У фоні відправ запит за свіжими.
- Коли прийдуть нові - онови UI.
5. Уникнення "дубльованих запитів"
Якщо компонент A і компонент B одночасно роблять один і той самий запит:
fetch('/api/user')
fetch('/api/user')без кешу сервер отримає два запити. З кешем (або бібліотекою на кшталт React Query) - лише один запит, а обидва компоненти отримають той самий результат з кешу.
Це називається deduplication (дедуплікація запитів).
6. Оптимізація UX при навігації
Якщо ти:
- відкрив сторінку списку (
/products), - потім перейшов на картку товару (
/products/42), - а потім повернувся назад,
то без кешу сторінка списку знову завантажиться з нуля. З кешем - список вже в пам'яті, і React покаже його миттєво.
Як кешувати в React на практиці
1. Вручну через Map або localStorage
const cache = new Map();
async function fetchWithCache(url) {
if (cache.has(url)) return cache.get(url);
const res = await fetch(url);
const data = await res.json();
cache.set(url, data);
return data;
}Плюси: просто, працює. Мінуси: немає інвалідації, застарілі дані, дублювання логіки.
2. Через React Query (TanStack Query)
Сучасний стандарт для кешування даних у React-застосунках:
import { useQuery } from '@tanstack/react-query';
function User({ id }) {
const { data, isLoading } = useQuery({
queryKey: ['user', id],
queryFn: () => fetch(`/api/users/${id}`).then(r => r.json()),
staleTime: 5 * 60 * 1000, // 5 хвилин кеш
});
if (isLoading) return <p>Завантаження...</p>;
return <p>{data.name}</p>;
}React Query:
- кешує дані в пам'яті (
QueryClient); - робить deduplication;
- керує
staleіrefetch; - автоматично оновлює при фокусі вкладки;
- можна задати
staleTime,cacheTime,refetchOnMountта ін.
3. Через SWR (by Vercel)
Легка бібліотека, побудована на концепції Stale-While-Revalidate:
import useSWR from 'swr';
const fetcher = url => fetch(url).then(r => r.json());
function User({ id }) {
const { data, error, isLoading } = useSWR(`/api/users/${id}`, fetcher);
if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error...</p>;
return <p>{data.name}</p>;
}SWR автоматично:
- кешує дані за ключем (
/api/users/${id}); - оновлює фонові дані при поверненні на сторінку;
- дозволяє використовувати
mutate()для ручного оновлення кешу.
4. Persisted cache (збереження кешу між сесіями)
React Query, SWR і Apollo Client підтримують persist-кеш:
- зберігає кеш у
localStorageабоIndexedDB; - при перезапуску застосунку - дані миттєво доступні;
- API-запит виконується у фоні для синхронізації.
ПІДСУМОК
| Причина | Навіщо кешувати |
|---|---|
| Швидкість | Миттєве відображення даних без лоадерів |
| UX | Стабільний інтерфейс при навігації і поверненнях |
| Оптимізація мережі | Менше запитів → менша latency і навантаження |
| Deduplication | Один запит - багато споживачів |
| SWR-підхід | Показує старе → оновлює нове |
| Офлайн | Можна працювати без мережі |
| Стійкість | Навіть при мережевій помилці UX не ламається |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.