Ответ 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 для разработчиков, вы можете точно видеть, как долго и что делает запрос:
Поскольку ответ не имеет тела, время ответа будет намного меньше, потому что меньше данных для передачи. Но есть еще ответ. и все еще есть все накладные расходы на подключение к удаленному серверу.
Преимущества
- Контент всегда свежий
- Отправлен только один запрос "Полный"
- Девять запросов гораздо более тонкие, только содержащие заголовки
- Более эффективный
Недостатки
- Показывает максимальное количество запросов
- Все еще выполняет поиск 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
- это имеет все преимущества использования параметра запроса для перебора кеша, но без проблемы отключения кэширования прокси.