Добро пожаловать в первую из серии статей об общих знаниях о масштабном запуске одностраничного приложения в производственной среде!
В этом выпуске мы обсуждаем лучшие практики кэширования ресурсов в одностраничном приложении - Angular / AngularJs / React / Vue или аналогичных - для достижения баланса между производительностью, гибкостью и защитой от удара в ногу.
Сначала предположим, что ваше приложение имеет процесс сборки (веб-пакет или другой) для создания типичных ресурсов *.js
, *.css
, *.html
.
Как только процесс сборки будет завершен, вы получите 2 класса ресурсов:
- «Неизменяемые ресурсы» с именем файла, уникальным для этой сборки, например
main.8d7a94ef1418343a7897.js
, - «Mutable Resources» с постоянным именем файла во всех сборках, например
index.html
TL; DR;
- Для неизменяемых ресурсов убедитесь, что ваш сервер отвечает следующими заголовками HTTP:
Cache-Control: public, max-age=31536000
- Это инструктирует браузеры (и все прокси-серверы, которые играли роль в доставке этого контента в браузер) использовать кэшированную копию, где это возможно, в течение следующего 1 года. Это идеально, так как имя этого файла было сгенерировано с хешем содержимого файла, и мы знаем, что имя файла для этой копии файла никогда не изменится.
- Для изменяемых ресурсов убедитесь, что ваш сервер отвечает следующими заголовками HTTP:
Cache-Control: max-age=30
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
- Обеспечивая возврат ETag, это означает, что браузер может выдавать условный
GET
запрос в последующих запросах на получение новой копии файла, только если файл был обновлен на вашем сервере. - Обратите внимание, что мы также указываем браузеру кэшировать на 30 секунд. В случае, если мы введем ошибку, из-за которой страница постоянно обновляется, мы избегаем перегружать наши серверы тоннами запросов.
Детали
А как насчет использования Cache-Control : immutable
?
Это новое значение расширения управления кешем может показаться соблазнительным, но предпочтительнее использовать более традиционные значения для достижения более ожидаемого поведения в браузерах. Некоторые браузеры либо не понимают, либо игнорируют директиву immutable
- https://stackoverflow.com/questions/41936772/which-browsers-support-cache-control-immutable - https://stackoverflow.com/questions / 52762478 / причина-почему-google-chrome-ignoring-cache-control-header
Почему бы не использовать Cache-Control: no-store, must-revalidate
?
Использование no-store, must-revalidate
может быть полезно в сценариях, когда мы хотим строго не кэшировать какой-либо контент, особенно конфиденциальный.
Однако, поскольку наше приложение представляет собой SPA, состоящий из ресурсов *.js
, *.css
, *.html
, которые по определению не могут быть чувствительными, мы предпочитаем, чтобы кеш браузера, где это возможно, оптимизировался для более быстрой загрузки
Почему Cache-Control: max-age=30
?
На случай, если мы случайно введем ошибку, которая приведет к постоянному обновлению нашего приложения, мы защищаем наши серверы от перегрузки, сообщая браузеру о необходимости кэширования ресурсов на срок до 30 секунд.
После нескольких циклов обновления большинство браузеров должны обнаружить неисправность и предотвратить бесконечное продолжение цикла.
Примечание. Мнения принадлежат мне и не отражают точку зрения или положение моего работодателя.