Назад | Перейти на главную страницу

Кэширование / выборка ресурсов HTTP

Я пытаюсь оптимизировать страницу и наблюдаю странное поведение. Каждый раз, когда я щелкаю ссылку на страницу, все ресурсы извлекаются с сервера, отвечая 200. Однако, когда я обновляю страницу (в частности, F5 в Firefox) все ресурсы возвращают 304 и, конечно, в результате страница загружается намного быстрее.

Главная страница возвращает 200 в обоих случаях. В случае обновления If-Modified-Since заголовки отправляются с запросами к ресурсам. Однако в случае «щелчка по ссылке» это не так. В чем причина этого и могу ли я это контролировать?

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

Если вы знаете, что ресурсы не изменятся, вы можете явно указать браузеру кэшировать объекты на фиксированный период времени. Отличный прием, можно сказать, кеширование на годы - затем просто немного измените URL-адрес, чтобы принудительно обновить (например, http://.../images/test.jpg?1 и замените 1 на 2, 3, 4 и т. д.). Некоторые платформы делают это автоматически, добавляя последнюю измененную метку времени.

1) .htaccess Электронные теги (из http://stuntsnippets.com/etags-htaccess/)

FileETag MTime Size
<ifmodule mod_expires.c>
  <filesmatch "\.(jpg|gif|png|css|js)$">
       ExpiresActive on
       ExpiresDefault "access plus 1 year"
   </filesmatch>
</ifmodule>

Полная документация: http://httpd.apache.org/docs/2.0/mod/core.html

2) .htaccess Cache-Control (из http://www.askapache.com/htaccess/apache-speed-cache-control.html)

# 480 weeks
<filesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
Header set Cache-Control "max-age=290304000, public"
</filesMatch>

# 2 DAYS
<filesMatch "\.(xml|txt)$">
Header set Cache-Control "max-age=172800, public, must-revalidate"
</filesMatch>

# 2 HOURS
<filesMatch "\.(html|htm)$">
Header set Cache-Control "max-age=7200, must-revalidate"
</filesMatch>

Полная документация: http://httpd.apache.org/docs/2.0/mod/mod_expires.html

Почему это происходит

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

Я считаю, что браузер Chrome (нажмите f12, вкладка «Сеть») лучше иллюстрирует это, чем Firefox.

Каждый раз, когда я щелкаю ссылку на страницу, все ресурсы извлекаются с сервера, отвечая 200.

Скорее всего, происходит следующее: когда вы «переходите по ссылке» (что должно быть таким же, как при прямом вводе URL-адреса), вы видите 200 ответов, которые представляют собой смесь реальных запросов и кешированные в браузере ответы. Это нормальное поведение. Chrome иллюстрирует ответы «из кеша», явно указывая «из кеша» для каждого ресурса на вкладке сети. Я считаю, что FF иллюстрирует это как седой ответы на временной шкале.

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

Однако, когда я обновляю страницу (в частности, F5 в Firefox), все ресурсы возвращают 304 и, конечно же, в результате страница загружается намного быстрее.

Когда вы нажимаете F5, вы принудительно отправляете запрос, чтобы не игнорировать кеш полностью, а еще раз проверить на сервере, изменился ли он. Заголовки ваших запросов содержат If-Modified-Since потому что он все еще доступен из кеша. Возвращается 304, и ваш браузер использует кэшированную версию, будучи уверенным, что версия сервера не изменилась.

Переход по ссылке = Использовать кэшированные данные.

F5 = Отправить запросы еще раз.

Ctrl + F5 = Отправить запросы снова, но также игнорировать локальный кеш.

Главная страница возвращает 200 в обоих случаях.

Кеширование браузера, вероятно, отключено для главной страницы (возможно, для всего содержимого .html по умолчанию) посредством возвращаемых для нее заголовков ответов. Из-за этого он не может отправить If-Modified-Since в обновленном запросе, потому что он не существует локально в кеше, и поэтому нет даты для сравнения содержимого. Потому что нет If-Modified-Since отправленный в запросе, сервер должен ответить еще 200 с полным содержимым страницы.

В случае обновления заголовки If-Modified-Since отправляются вместе с запросами к ресурсам.

Поскольку элементы ресурсов доступны из кеша, и поэтому есть дата для отправки - дата, когда элементы были добавлены в кеш браузера.

Однако в случае «щелчка по ссылке» это не так. В чем причина этого и могу ли я это контролировать?

Поскольку браузер не отправляет заголовки If-Modified-Since при извлечении из локального кеша. Ответ 200 - это кешированный. Вам не нужно контролировать который в качестве таких.

Ничто из этого не объясняет, почему он загружается быстрее, когда вы нажимаете F5. Вы уверены, что это правильно?

Отдельно стоит отметить «эвристическое кеширование» браузера. Это поведение, которое браузер принимает, когда кэширование не определяется явно заголовками ответа, а по сути является поведением «наилучшего предположения». Естественно, это отличается для каждого браузера.

Было бы полезно, если бы вы включили примеры заголовков запроса и ответа для обоих сценариев.

Явное обновление заставляет браузер включать prama: no-cache в запрос - это означает, что все промежуточные кеши (включая прокси) должны пересылать запрос на исходный сервер. Когда вы нажимаете на ссылку, контент может поступать из кеша вашего браузера, промежуточного прокси, обратного прокси или исходного сервера.

все ресурсы возвращают 304 и, конечно, страница загружается намного быстрее

Но вы получите еще более быстрый ответ, если снабдите контент инструкциями, позволяющими браузеру кэшировать его, то есть директивой expires или cache-control: max-age). Условные запросы действительно ускоряют доступ только при работе с очень большими файлами (PDF, видео и т. Д.). Обратите внимание, что большинство браузеров сообщают о состоянии 200 для таких операций при извлечении из локального кеша, но это будет намного быстрее, чем обратная ссылка на источник.

В случае обновления заголовки If-Modified-Since отправляются вместе с запросами к ресурсам. Однако в случае "щелчок по ссылке" они не

В самом деле? Ты уверен?

Это может произойти, если вы не включаете инструкцию кэширования max-age / expires - это настолько глупо, что я никогда не проверял, как она себя ведет.

Для меня это звучит как настройка браузера, и, листая параметры, которые я вижу в Firefox на моем (Windows 7) нетбуке, я не вижу ничего, что позволило бы вам управлять им.

Боюсь, что это нет.