Подтвердить что ты не робот

Кэширование файлов: строка запроса vs Last-Modified?

Я дурачился со способами кэширования ресурсов моего сайта и заметил, что большинство сайтов, похожих на мои, используют строки запросов для переопределения кэширования (например: /css/style.css?v=124942823)

Впоследствии я заметил, что всякий раз, когда я сохранял свой файл style.css, последние измененные заголовки "обновлялись", что делало строку запроса ненужной.

Вот мне и интересно

  • Почему так много веб-сайтов используют метод "строка запроса" вместо того, чтобы просто работать с последним измененным заголовком?
  • Должен ли я сбросить последний измененный заголовок и просто работать со строками запроса? (Есть ли какое-то конкретное преимущество в этом?)
4b9b3361

Ответ 1

TL; DR

Почему так много сайтов используют метод "строка запроса", вместо того, чтобы просто позволить последнему модифицированному заголовку выполнять свою работу?

Изменение строки запроса изменяет URL-адрес, обеспечивая, чтобы контент был "свежим".

Должен ли я отключить заголовок Last-modified и просто работать с строками запроса?

Нет. Хотя это почти правильный ответ.


В Интернете используются три основные стратегии кэширования:

  • Нет кэширования или кэширования отключено
  • Использование валидации/условных запросов
  • Кэширование навсегда

Чтобы проиллюстрировать все три, рассмотрим следующий сценарий:

Пользователь обращается к веб-сайту в первый раз, загружает десять страниц и оставляет. Каждая страница загружает один и тот же файл css. Для каждой из вышеперечисленных стратегий кеширования будет выполнено количество запросов?

Нет кэширования: 10 запросов

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

Преимущества

  • Контент всегда свежий
  • Не требуется усилий/управления

Недостатки

  • Наименее эффективный контент всегда передается

Запросы проверки: 10 запросов

Если Last-Modified или Etag, будет также 10 запросов. Однако 9 из них будут только заголовками, и никакое тело не будет передано. Клиенты используют условные запросы, чтобы избежать повторной загрузки того, что у него уже есть. Возьмем, к примеру, файл css для этого сайта.

В первый раз, когда запрашивается файл, происходит следующее:

$ curl -i http://cdn.sstatic.net/stackoverflow/all.css
HTTP/1.1 200 OK
Server: cloudflare-nginx
Date: Mon, 12 May 2014 07:38:31 GMT
Content-Type: text/css
Connection: keep-alive
Set-Cookie: __cfduid=d3fa9eddf76d614f83603a42f3e552f961399880311549; expires=Mon, 23-Dec-2019 23:50:00 GMT; path=/; domain=.sstatic.net; HttpOnly
Cache-Control: public, max-age=604800
Last-Modified: Wed, 30 Apr 2014 22:09:37 GMT
ETag: "8026e7dfc064cf1:0"
Vary: Accept-Encoding
CF-Cache-Status: HIT
Expires: Mon, 19 May 2014 07:38:31 GMT
CF-RAY: 1294f50b2d6b08de-CDG
.avatar-change:hover{backgro.....Some KB of content

Следующий запрос для того же URL-адреса будет выглядеть следующим образом:

$ curl -i -H "If-Modified-Since:Wed, 30 Apr 2014 22:09:37 GMT" http://cdn.sstatic.net/stackoverflow/all.css
HTTP/1.1 304 Not Modified
Server: cloudflare-nginx
Date: Mon, 12 May 2014 07:40:11 GMT
Content-Type: text/css
Connection: keep-alive
Set-Cookie: __cfduid=d0cc5afd385060dd8ba26265f0ebf40f81399880411024; expires=Mon, 23-Dec-2019 23:50:00 GMT; path=/; domain=.sstatic.net; HttpOnly
Cache-Control: public, max-age=604800
Last-Modified: Wed, 30 Apr 2014 22:09:37 GMT
ETag: "8026e7dfc064cf1:0"
Vary: Accept-Encoding
CF-Cache-Status: HIT
Expires: Mon, 19 May 2014 07:40:11 GMT
CF-RAY: 1294f778e75d04a3-CDG

Обратите внимание, что тела нет, а ответ 304 Not Modified. Это говорит клиенту, что контент, который он уже имеет (в локальном кеше) для этого URL-адреса, все еще свежи.

Это не значит, что это оптимальный сценарий. Используя инструменты, такие как вкладка сети инструментов Chrome для разработчиков, вы можете точно видеть, как долго и что делает запрос:

enter image description here

Поскольку ответ не имеет тела, время ответа будет намного меньше, потому что меньше данных для передачи. Но есть еще ответ. и все еще есть все накладные расходы на подключение к удаленному серверу.

Преимущества

  • Контент всегда свежий
  • Отправлен только один запрос "Полный"
  • Девять запросов гораздо более тонкие, только содержащие заголовки
  • Более эффективный

Недостатки

  • Показывает максимальное количество запросов
  • Все еще выполняет поиск DNS
  • Необходимо установить соединение с удаленным сервером
  • Не работает в автономном режиме
  • Может потребоваться конфигурация сервера

Кэширование навсегда: 1 запрос

Если нет etags, никакого последнего измененного заголовка и только заголовок expires, установленный далеко в будущем - только самый первый доступ к URL-адресу приведет к любой связи с удаленным сервером. Это известный? наилучшая практика для лучшей производительности интерфейса. Если это так, для последующих запросов клиент будет считывать содержимое из собственного кеша и вообще не связываться с удаленным сервером.

Это имеет четкие преимущества в производительности, которые особенно важны для мобильных устройств, где латентность может быть значительной (мягко говоря).

Преимущества

  • Самый эффективный, контент передается только один раз

Недостатки

  • Изменить URL-адрес , чтобы существующие пользователи не загружали устаревшие кешированные версии
  • Большинство усилий по настройке/управлению

Не используйте строки запроса для перебора кеша

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

Использование строк запроса предотвращает кэширование прокси., в приведенной ниже цитате автор демонстрирует, что запрос от сервера веб-браузера ↔ proxy cache ↔ не использует кеш-прокси:

Загрузка mylogo.gif? v = 1.2 дважды (очистка кеша между ними) в этих заголовках:

>> GET http://stevesouders.com/mylogo.gif?v=1.2 HTTP/1.1
<< HTTP/1.0 200 OK
<< Date: Sat, 23 Aug 2008 00:19:34 GMT
<< Expires: Tue, 21 Aug 2018 00:19:34 GMT
<< X-Cache: MISS from someserver.com
<< X-Cache-Lookup: MISS from someserver.com

>> GET http://stevesouders.com/mylogo.gif?v=1.2 HTTP/1.1
<< HTTP/1.0 200 OK
<< Date: Sat, 23 Aug 2008 00:19:47 GMT
<< Expires: Tue, 21 Aug 2018 00:19:47 GMT
<< X-Cache: MISS from someserver.com
<< X-Cache-Lookup: MISS from someserver.com

Здесь ясно, что второй ответ не был прокси-сервером: кеширующие заголовки ответов говорят, что MISS, значения Date и Expires меняются, и хвост журнала доступа stevesouders.com показывает два раза.

Это не следует воспринимать легкомысленно - при обращении к сайту, физически находящемуся на другой стороне мирового времени ответа, может быть очень медленно. Получение ответа от прокси-сервера, расположенного вдоль маршрута, может означать разницу между используемым веб-сайтом или нет - в случае ресурсов cached-forever это означает, что первая загрузка URL-адреса медленная, в случае использования запросов проверки означает, что весь сайт будет вялым.

Вместо активов контроля версий

"Лучшее" решение - это файлы управления версиями, так что всякий раз, когда изменяется содержимое, он делает URL. Обычно это будет автоматизировано как часть процесса сборки.

Однако почти компромисс заключается в реализации правила перезаписи например

# ------------------------------------------------------------------------------
# | Filename-based cache busting                                               |
# ------------------------------------------------------------------------------

# If you're not using a build process to manage your filename version revving,
# you might want to consider enabling the following directives to route all
# requests such as `/css/style.12345.css` to `/css/style.css`.

# To understand why this is important and a better idea than `*.css?v231`, read:
# http://stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring

<IfModule mod_rewrite.c>
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteRule ^(.+)\.(\d+)\.(js|css|png|jpe?g|gif)$ $1.$3 [L]
</IfModule>

Таким образом, запрос foo.123.css обрабатывается сервером как foo.css - это имеет все преимущества использования параметра запроса для перебора кеша, но без проблемы отключения кэширования прокси.

Ответ 2

Заголовок Last-Modified применяется по-разному в браузерах, но, как правило, браузер выдаст условный запрос GET, на который сервер должен ответить, если необходимо обновить кеш. Например, в Firefox...

Заголовок ответа "Last-Modified" может использоваться как слабый валидатор. Он считается слабым, потому что он имеет только 1-секундную разрешающую способность. Если Заголовок "Last-Modified" присутствует в ответе, тогда клиент может выдать заголовок запроса "If-Modified-Since" для проверки кэширования документ.

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

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

Возможно, стоит отметить, что документация по конвейеру ресурсов рельсов (http://guides.rubyonrails.org/asset_pipeline.html) приводит к 3 преимуществам для отпечатков пальцев по временной метке запроса:

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

Дополнительные сведения и рекомендации по кэшированию: https://developers.google.com/speed/docs/best-practices/caching