Обожаю ваш тайник ❤️

Пользователи, загружающие ваш сайт во второй раз, будут использовать свой HTTP-кеш, поэтому убедитесь, что он работает хорошо.

Этот пост является дополнением к видеоролику «Любите свой кеш» , который является частью расширенного контента Chrome Dev Summit 2020. Обязательно посмотрите это видео:

Когда пользователи загружают ваш сайт во второй раз, их браузер будет использовать ресурсы своего HTTP-кеша, чтобы ускорить загрузку. Но стандарты кэширования в Интернете датируются 1999 годом, и они определены довольно широко: определение того, может ли файл, например CSS или изображение, быть снова получен из сети или загружен из вашего кеша, является несколько неточным. наука.

В этом посте я расскажу о разумном, современном варианте кэширования по умолчанию, который на самом деле вообще не кэширует . Но это всего лишь значение по умолчанию, и оно, конечно, более тонкое, чем просто «отключение». Читайте дальше!

Цели

Когда сайт загружается второй раз, у вас есть две цели:

  1. Убедитесь, что ваши пользователи получают самую последнюю доступную версию — если вы что-то изменили, это должно быть отражено быстро.
  2. Сделайте №1, получая как можно меньше информации из сети.

В самом широком смысле вы хотите отправлять своим клиентам только самые незначительные изменения, когда они снова загружают ваш сайт. А структурирование вашего сайта для обеспечения наиболее эффективного распространения любых изменений является сложной задачей (подробнее об этом ниже и в видео).

Сказав это, у вас есть и другие возможности, когда вы рассматриваете возможность кэширования — возможно, вы решили позволить HTTP-кешу браузера пользователя удерживать ваш сайт в течение длительного времени, чтобы для его обслуживания вообще не требовались сетевые запросы. Или вы создали сервис-воркера, который будет обслуживать сайт полностью в автономном режиме, прежде чем проверять его актуальность. Это крайний вариант, который действителен и используется для многих веб-приложений, ориентированных в первую очередь на офлайн-приложения, но Интернет не обязательно должен быть в крайнем режиме только для кэша или даже в исключительном режиме только для сети.

Фон

Как веб-разработчики, мы все привыкли к идее наличия «устаревшего кэша». Но мы почти инстинктивно знаем, какие инструменты доступны для решения этой проблемы: выполнить «принудительное обновление», открыть окно в режиме инкогнито или использовать некоторую комбинацию инструментов разработчика вашего браузера для очистки данных сайта.

Обычные пользователи Интернета не имеют такой роскоши. Таким образом, хотя у нас есть некоторые основные цели — обеспечить, чтобы наши пользователи хорошо проводили время со второй загрузкой, также очень важно убедиться, что они не испытывают затруднений и не застревают. (Посмотрите видео, если хотите услышать, как я рассказываю о том, как мы чуть не застряли на сайте web.dev/live !)

Для справки: действительно распространенной причиной «устаревшего кэша» на самом деле является значение по умолчанию для кэширования, установленное в эпоху 1999 года. Он опирается на заголовок Last-Modified :

Диаграмма, показывающая, как долго различные ресурсы кэшируются браузером пользователя.
Ресурсы, созданные в разное время (серым цветом), будут кэшироваться в разное время, поэтому вторая загрузка может получить комбинацию кэшированных и свежих ресурсов.

Каждый загружаемый вами файл сохраняется еще 10 % от его текущего срока службы в том виде, в котором его видит ваш браузер. Например, если index.html был создан месяц назад, он будет кэшироваться вашим браузером еще примерно три дня.

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

Хорошо освещенный путь

Современный вариант кэширования по умолчанию — вообще не выполнять кеширование и использовать CDN , чтобы сделать ваш контент ближе к пользователям. Каждый раз, когда пользователь загружает ваш сайт, он заходит в сеть, чтобы проверить, обновлен ли он. Этот запрос будет иметь низкую задержку, поскольку он будет предоставлен CDN, географически близкой к каждому конечному пользователю.

Вы можете настроить свой веб-хост для ответа на веб-запросы с помощью этого заголовка:

Cache-Control: max-age=0,must-revalidate,public

По сути, это говорит; файл действителен в течение какого-то времени, и вы должны проверить его в сети, прежде чем сможете использовать его снова (в противном случае это только «предложено»).

Этот процесс проверки относительно дешев с точки зрения передаваемых байтов — если большой файл изображения не изменился, ваш браузер получит небольшой ответ 304 — но он требует задержки , поскольку пользователю все равно приходится выходить в сеть, чтобы узнать это. И это основной недостаток такого подхода. Это может очень хорошо работать для людей с быстрым соединением в первом мире и где выбранная вами CDN имеет хорошее покрытие, но не для тех людей, которые могут использовать более медленное мобильное соединение или использовать плохую инфраструктуру.

Тем не менее, это современный подход, который используется по умолчанию в популярной CDN Netlify , но его можно настроить практически на любой CDN. Для хостинга Firebase вы можете включить этот заголовок в раздел хостинга вашего файла firebase.json:

"headers": [
  // Be sure to put this last, to not override other headers
  {
    "source": "**",
    "headers": [ {
      "key": "Cache-Control",
      "value": "max-age=0,must-revalidate,public"
    }
  }
]

Поэтому, хотя я по-прежнему предлагаю это как разумный вариант по умолчанию, это всего лишь вариант по умолчанию! Читайте дальше, чтобы узнать, как вмешаться и обновить настройки по умолчанию.

URL-адреса с отпечатками пальцев

Включив хеш содержимого файла в имя ресурсов, изображений и т. д., обслуживаемых на вашем сайте, вы можете гарантировать, что эти файлы всегда будут иметь уникальное содержимое — например, это приведет к созданию файлов с именем sitecode.af12de.js . Когда ваш сервер отвечает на запросы этих файлов, вы можете безопасно указать браузерам вашего конечного пользователя кэшировать их в течение длительного времени, настроив их с помощью этого заголовка:

Cache-Control: max-age=31536000,immutable

Это значение равно году в секундах. И согласно спецификации, это фактически равно «навсегда».

Важно: не создавайте эти хэши вручную — это слишком много ручной работы! Вы можете использовать такие инструменты, как Webpack, Rollup и т. д., которые помогут вам в этом. Обязательно прочитайте о них больше в Tooling Report .

Помните, что не только JavaScript может извлечь выгоду из URL-адресов с отпечатками пальцев; такие ресурсы, как значки, CSS и другие неизменяемые файлы данных, также можно назвать таким образом. (И обязательно посмотрите видео выше, чтобы узнать больше о разделении кода, которое позволяет отправлять меньше кода при каждом изменении вашего сайта.)

Независимо от того, как ваш сайт подходит к кэшированию, такие файлы с отпечатками пальцев невероятно ценны для любого сайта, который вы можете создать. Большинство сайтов просто не меняются в каждом выпуске.

Конечно, мы не можем переименовать наши «дружественные» страницы, ориентированные на пользователя, таким образом: переименовать файл index.html в index.abcd12.html — это невозможно, вы не можете указывать пользователям каждый раз переходить на новый URL-адрес. они загружают ваш сайт! Эти «дружественные» URL-адреса невозможно переименовать и кэшировать таким образом, что подводит меня к возможному компромиссному варианту.

Золотая середина

Очевидно, что когда дело доходит до кэширования, есть место для золотой середины. Я представил два крайних варианта; кэшировать никогда или кэшировать навсегда . И будет ряд файлов, которые вы, возможно, захотите на какое-то время кэшировать, например «дружественные» URL-адреса, о которых я упоминал выше.

Если вы хотите кэшировать эти «дружественные» URL-адреса и их HTML-код, стоит подумать, какие зависимости они включают, как их можно кэшировать и как кэширование их URL-адресов в течение некоторого времени может повлиять на вас. Давайте посмотрим на HTML-страницу, содержащую такое изображение:

<img src="/images/foo.jpeg" loading="lazy" />

Если вы обновите или измените свой сайт, удалив или изменив это лениво загружаемое изображение, пользователи, просматривающие кэшированную версию вашего HTML, могут получить неправильное или отсутствующее изображение, поскольку они все еще кэшируют исходный файл /images/foo.jpeg , когда они повторно посетите ваш сайт.

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

В общем, большинство руководств по кэшированию будут говорить о таких настройках: хотите ли вы кэшировать на час, несколько часов и так далее. Чтобы настроить этот тип кэша, используйте такой заголовок (который кэшируется на 3600 секунд или один час):

Cache-Control: max-age=3600,immutable,public

И последнее. Если вы создаете актуальный контент, к которому пользователи обычно могут получить доступ только один раз (например, новостные статьи!), я считаю, что его никогда не следует кэшировать, и вам следует использовать разумный вариант по умолчанию, указанный выше. Я думаю, что мы часто переоцениваем ценность кэширования по сравнению с желанием пользователя всегда видеть самый последний и лучший контент, например, критические обновления новостей или текущие события.

Варианты, отличные от HTML

Помимо HTML, есть и другие варианты файлов, которые находятся посередине:

  • В общем, ищите активы, которые не влияют на других.

    • Например: избегайте CSS, так как он вызывает изменения в способе отображения вашего HTML.
  • Большие изображения, которые используются в своевременных статьях.

    • Ваши пользователи, вероятно, не будут посещать одну статью более нескольких раз, поэтому не кэшируйте фотографии или изображения героев навсегда и не тратьте впустую память.
  • Актив, который представляет собой что-то, что само по себе имеет срок службы.

    • Данные JSON о погоде могут публиковаться только каждый час, поэтому вы можете кэшировать предыдущий результат на час — он не изменится в вашем окне.
    • Сборки проекта с открытым исходным кодом могут быть ограничены по скорости, поэтому кэшируйте изображение состояния сборки до тех пор, пока не появится возможность изменения статуса.

Краткое содержание

Когда пользователи загружают ваш сайт во второй раз, вы уже получили вотум доверия: они хотят вернуться и получить больше того, что вы предлагаете. На этом этапе речь идет не только о сокращении времени загрузки, и у вас есть множество доступных опций, позволяющих гарантировать, что ваш браузер выполняет только ту работу, которая ему необходима для обеспечения быстрой и актуальной работы.

Кэширование — не новая концепция в Интернете, но, возможно, для него требуется разумный вариант по умолчанию — подумайте об использовании одного из них и решительно поддержите более эффективные стратегии кэширования, когда они вам понадобятся. Спасибо за чтение!

См. также

Общее руководство по HTTP-кэшу см. в разделе Предотвращение ненужных сетевых запросов с помощью HTTP-кэша .