← Назад к вопросам

Где определяется кэширование?

2.2 Middle🔥 181 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Где определяется кэширование

Кэширование в веб-приложениях определяется на нескольких уровнях и регулируется разными механизмами. Это важнейшая тема для оптимизации производительности фронтенда.

Уровни кэширования

1. HTTP кэширование (самое главное)

Регулируется HTTP заголовками в ответе сервера. Это контролирует, как браузер и промежуточные прокси (CDN, nginx) сохраняют и переиспользуют ресурсы.

Основные заголовки:

// На сервере (Express.js пример)
app.get('/api/products', (req, res) => {
  // Разрешить браузеру кэшировать на 1 час
  res.set('Cache-Control', 'public, max-age=3600');
  res.json(productsData);
});

app.get('/images/logo.png', (req, res) => {
  // Кэшировать на 1 год (для статических assets с версией)
  res.set('Cache-Control', 'public, max-age=31536000');
  res.sendFile('logo.png');
});

app.get('/api/user-profile', (req, res) => {
  // Не кэшировать (данные персональные)
  res.set('Cache-Control', 'no-cache, no-store, must-revalidate');
  res.json(userProfile);
});

Значения Cache-Control:

  • public — кэш может быть использован браузером и промежуточными кэшами (CDN)
  • private — кэш только для браузера пользователя (не для CDN/прокси)
  • max-age=3600 — кэшировать на 3600 секунд (1 час)
  • no-cache — всегда проверить с сервером перед использованием из кэша
  • no-store — не кэшировать вообще
  • must-revalidate — кэш истекает, если есть ошибка сети

2. ETag и Last-Modified (переиспользование кэша)

Эти заголовки позволяют браузеру проверить, изменился ли ресурс:

// На сервере
app.get('/api/data', (req, res) => {
  const data = { id: 1, name: 'Item' };
  const etag = '"abc123"';
  
  res.set('ETag', etag);
  res.set('Cache-Control', 'no-cache');
  
  if (req.get('If-None-Match') === etag) {
    return res.sendStatus(304);
  }
  
  res.json(data);
});

3. Service Workers (кэширование на клиенте)

Дает полный контроль над кэшированием с клиентской стороны:

// service-worker.js
const CACHE_NAME = 'my-app-v1';

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME).then((cache) => {
      return cache.addAll([
        '/',
        '/css/style.css',
        '/js/app.js'
      ]);
    })
  );
});

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request).then((response) => {
      if (response) return response;
      return fetch(event.request);
    })
  );
});

4. localStorage и sessionStorage

Для приложения, когда HTTP кэширования недостаточно:

localStorage.setItem('userData', JSON.stringify({
  id: 1,
  name: 'John',
  timestamp: Date.now()
}));

const cached = JSON.parse(localStorage.getItem('userData'));
if (cached && Date.now() - cached.timestamp < 3600000) {
  useData(cached);
} else {
  fetchFreshData();
}

5. React useMemo для кэширования вычислений

function UserProfile({ userId }) {
  const userData = useMemo(() => {
    return fetchUserData(userId);
  }, [userId]);
  
  return <div>{userData.name}</div>;
}

Практический пример: API клиент с кэшированием

class ApiClient {
  constructor() {
    this.cache = new Map();
  }

  async get(url, options = {}) {
    const cacheKey = url + JSON.stringify(options);
    
    if (this.cache.has(cacheKey)) {
      const { value, expiry } = this.cache.get(cacheKey);
      if (Date.now() < expiry) {
        return value;
      }
      this.cache.delete(cacheKey);
    }

    const data = await fetch(url, options).then(r => r.json());
    
    this.cache.set(cacheKey, {
      value: data,
      expiry: Date.now() + 300000
    });
    return data;
  }
}

Стратегии кэширования

Cache First: для статических ассетов

event.respondWith(
  caches.match(event.request)
    .then((response) => response || fetch(event.request))
);

Network First: для API данных

event.respondWith(
  fetch(event.request)
    .catch(() => caches.match(event.request))
);

Вывод

Кэширование определяется на разных уровнях:

  1. HTTP заголовки (Cache-Control, ETag) — основной способ
  2. Service Workers — для offline режима
  3. localStorage/sessionStorage — для персистентных данных
  4. JavaScript Map — для временного кэша в памяти
  5. useMemo — для кэша вычислений в React

Для оптимальной производительности используй всё вместе в зависимости от случая.

Где определяется кэширование? | PrepBro