Что такое кэширование статических файлов в ASP.NET Core?

«Что такое кэширование статических файлов в ASP.NET Core?» — вопрос из категории ASP.NET Core, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Кэширование статических файлов — это механизм, который инструктирует браузер клиента или промежуточные прокси-серверы сохранять копии статических ресурсов (CSS, JS, изображения, шрифты) локально на определенный срок. Это drastically сокращает количество запросов к серверу и ускоряет загрузку повторно посещаемых страниц.

Как работает? Сервер отправляет файл вместе с HTTP-заголовками, управляющими кэшем:

  • Cache-Control (современный): max-age=3600 — кэшировать на 1 час.
  • Expires (устаревший): Указывает точную дату истечения срока действия.
  • ETag / Last-Modified: Для условных запросов (проверка, изменился ли файл).

Настройка в ASP.NET Core: По умолчанию app.UseStaticFiles() использует кэширование. Настроить его можно через StaticFileOptions.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // ...
    app.UseStaticFiles(new StaticFileOptions
    {
        OnPrepareResponse = ctx =>
        {
            // Кэшировать статические файлы на 1 день (86400 секунд) в public кэше
            var headers = ctx.Context.Response.Headers;
            headers["Cache-Control"] = "public, max-age=86400";
            // Устаревший заголовок для совместимости
            headers["Expires"] = DateTime.UtcNow.AddDays(1).ToString("R");
        }
    });
}

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

  1. Агрессивное кэширование (для версионных файлов): Используйте для файлов с хэшем в имени (например, site.[hash].css). Их содержимое никогда не меняется, поэтому можно кэшировать на очень долгий срок.

    Cache-Control: public, max-age=31536000 // 1 год
  2. Умеренное кэширование (для часто изменяемых файлов): Для файлов без версии, которые могут обновляться.

    Cache-Control: public, max-age=3600 // 1 час
  3. Проверка актуальности (использование ETag): Браузер отправляет заголовок If-None-Match со значением ETag. Если файл не изменился, сервер отвечает 304 Not Modified (без тела файла), что экономит трафик.

Проблема инвалидации кэша и ее решение:

  • Проблема: Вы обновили site.css на сервере, но у пользователей в кэше старая версия.
  • Решение 1 (рекомендуемое): Использовать версионирование имен файлов через систему сборки (Webpack, Gulp) или query-строку (менее надежно). При изменении файла меняется и его имя, браузер запрашивает новый ресурс.
    • site.css -> site.a1b2c3d4.css
  • Решение 2: Использовать Cache-Control: no-cache (не "не кэшировать", а "кэшировать, но проверять с сервером каждый раз") для критичных к актуальности файлов.

**Для файлов, которые часто меняются (например, JSON API), кэширование на стороне клиента обычно не применяется или используется с коротким max-age.