Sobes.tech
Back to questions
Middle+
3

Как работает кэширование ресурсов в браузере — как браузер понимает, брать из кэша или грузить заново, как этим управлять? Какие есть способы кэширования, включая Service Worker?

Companies where asked
Mayflower

Answer from AI

sobes.tech AI

Браузер кэширует ресурсы (HTML, CSS, JS, изображения и др.) для ускорения загрузки и снижения нагрузки на сеть. При повторном запросе браузер решает, использовать ли кэш или загрузить ресурс заново, основываясь на HTTP-заголовках и политике кэширования.

Как браузер решает брать из кэша или нет

  • Cache-Control — основной заголовок, который задаёт правила кэширования. Например, max-age=3600 означает, что ресурс считается свежим в течение часа.
  • Expires — устаревший, но всё ещё поддерживаемый заголовок с датой истечения срока годности ресурса.
  • ETag — уникальный идентификатор версии ресурса. При повторном запросе браузер отправляет If-None-Match с ETag, сервер отвечает 304 Not Modified, если ресурс не изменился.
  • Last-Modified — дата последнего изменения ресурса. Аналогично ETag, браузер отправляет If-Modified-Since.

Если ресурс свежий и не истёк, браузер берёт его из кэша. Если нет — делает запрос на сервер с условием, чтобы проверить изменения.

Управление кэшированием

  • Настраивать заголовки на сервере (например, в nginx, Apache, или backend-приложении).
  • Использовать версионирование ресурсов (например, хеш в имени файла) для контроля обновлений.
  • В HTML можно использовать <meta http-equiv="Cache-Control" content="no-cache">, но это менее эффективно.

Способы кэширования

  1. HTTP-кэширование — стандартное кэширование через заголовки.
  2. LocalStorage / IndexedDB — для хранения данных на стороне клиента, не для ресурсов.
  3. Service Worker — скрипт, который работает между сетью и приложением, позволяет полностью контролировать кэширование, создавать офлайн-приложения.

Пример Service Worker для кэширования ресурсов:

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open('v1').then(cache => {
      return cache.addAll([
        '/',
        '/styles.css',
        '/script.js',
        '/image.png'
      ]);
    })
  );
});

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

Таким образом, Service Worker позволяет перехватывать запросы и отдавать ресурсы из кэша, даже если сеть недоступна.