> Какие данные кэшируются и как работает кэширование (JavaScript)

Уровень: senior · Роль: frontend · Язык: JavaScript · Категория: Технические вопросы

Компании: QueenInteractiveGamesLtd

Стек: Node.js, JavaScript, Go

> Пример ответа

Короткий ответ

Кэширование в frontend охватывает статические ресурсы (HTML, CSS, JS, изображения) через HTTP-кэш (Cache-Control, ETag), данные API - через service worker или in-memory (Redux, React Query), а также вычисления - через memoization (useMemo, reselect). Работа строится на стратегиях: stale-while-revalidate для данных, cache-first для статики, network-first для критичных запросов. Node.js добавляет кэширование в памяти (Redis, LRU-cache), Go - sync.Map или групповое кэширование (singleflight).

Подробное объяснение

Кэширование на frontend делится на три уровня:

  • HTTP-кэш: браузер хранит ответы сервера по заголовкам Cache-Control (max-age, no-cache, immutable) и ETag/Last-Modified для валидации. Статические файлы кэшируются надолго (1 год), API-ответы - на короткое время или с revalidation.
  • Service Worker: перехватывает запросы и реализует стратегии (cache-first, network-first, stale-while-revalidate). Используется для offline-first приложений и кэширования данных с фоновым обновлением.
  • In-memory кэш: Redux/React Query хранят данные в памяти с TTL и инвалидацией по ключам. Memoization (useMemo, useCallback, reselect) кэширует результаты вычислений до изменения зависимостей.
  • Node.js: серверное кэширование через Redis (shared cache) или in-memory LRU. Middleware кэширует ответы по URL или query-параметрам.
  • Go: sync.Map для конкурентного кэша, singleflight для предотвращения дублирующих запросов, групповое кэширование (groupcache).

Ключевые trade-off: объём кэша vs актуальность данных, время жизни vs частота обновлений, память клиента vs производительность.

На практике

  • Статика: настройка Cache-Control: public, max-age=31536000, immutable для хэшированных файлов. ETag для динамических ресурсов.
  • API: React Query с staleTime (например, 5 минут) и gcTime (30 минут). При фокусе окна - refetchOnWindowFocus с revalidation.
  • Service Worker: стратегия stale-while-revalidate для списка товаров - сначала из кэша, потом обновление в фоне.
  • Node.js: Redis для сессий и частых запросов (например, каталог). TTL 10 минут, инвалидация при изменении данных.
  • Go: singleflight для одного и того же запроса от множества горутин - первый выполняет, остальные ждут результат.

Инвалидация: по времени (TTL), по событию (мутация данных), по ключу (очистка конкретного кэша).

Пример кода

JAVASCRIPT
// React Query с кэшированием
import { useQuery } from '@tanstack/react-query';
function useProducts() {
return useQuery({
queryKey: ['products'],
queryFn: fetchProducts,
staleTime: 5 * 60 * 1000, // 5 минут до устаревания
gcTime: 30 * 60 * 1000, // 30 минут до удаления из кэша
refetchOnWindowFocus: true,
});
}
// Service Worker stale-while-revalidate
self.addEventListener('fetch', (event) => {
if (event.request.url.includes('/api/products')) {
event.respondWith(
caches.match(event.request).then((cached) => {
const fetchPromise = fetch(event.request).then((response) => {
caches.put(event.request, response.clone());
return response;
});
return cached || fetchPromise;
})
);
}
});
// Node.js in-memory LRU cache
import LRU from 'lru-cache';
const cache = new LRU({ max: 500, ttl: 1000 * 60 * 10 });
function getCachedData(key) {
if (cache.has(key)) return cache.get(key);
const data = fetchFromDB(key);
cache.set(key, data);
return data;
}

Как отвечать на собеседовании

Начни с трёхуровневой модели: HTTP, service worker, in-memory. Упомяни стратегии (cache-first, network-first, stale-while-revalidate) и когда какую применять. Добавь про инвалидацию: TTL, event-based, key-based. Для senior важно показать понимание trade-off: объём кэша vs свежесть данных, память vs скорость. Приведи пример из практики - как кэшировал список товаров с React Query и service worker для offline. Если спросят про Node.js/Go - расскажи про Redis, singleflight, конкурентный доступ.

Что проверяет интервьюер

  • Понимание уровней кэширования и их назначения.
  • Знание стратегий кэширования и когда их применять.
  • Умение проектировать инвалидацию кэша.
  • Опыт работы с конкретными инструментами (React Query, service worker, Redis).
  • Понимание trade-off между производительностью и актуальностью данных.

Типичные ошибки

  • Путать HTTP-кэш и service worker - это разные уровни.
  • Не учитывать инвалидацию кэша при мутациях данных.
  • Кэшировать всё подряд без TTL - приводит к устаревшим данным.
  • Игнорировать память клиента - слишком большой in-memory кэш вызывает проблемы.
  • В Go/Node.js забывать про конкурентный доступ и гонки данных при записи в кэш.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью