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

Агрессивное кэширование JavaScript

У меня возникла проблема, когда я вношу изменения в несколько файлов JavaScript, на которые ссылаются в файле HTML, но браузер не видит изменений. Он хранится в копии, сохраненной в браузере, хотя веб-сервер имеет более новую версию.

Пока я не заставляю браузер очищать кеш, я вижу изменения.

Является ли это конфигурацией веб-сервера? Мне нужно, чтобы мои файлы JavaScript никогда не кэшировались? Я видел некоторые интересные методы в Google Web Toolkit, где они фактически создают имя файла new JavaScript в любое время обновление сделано. Я считаю, что это предотвращает использование прокси-серверов и браузеров старых версий файлов JavaScript с одинаковыми именами.

Есть ли список лучших практик где-нибудь?

4b9b3361

Ответ 1

Мы добавляем номер сборки продукта в конец всего Javascript (и CSS и т.д.), например:

<script src="MyScript.js?4.0.8243">

Браузеры игнорируют все после отметки вопроса, но обновление вызывает новый URL-адрес, что означает перезагрузку кеша.

У этого есть дополнительное преимущество, которое вы можете установить заголовки HTTP, которые означают "никогда не кэшировать!"

Ответ 2

Он хранится в копии, сохраненной в браузере, хотя веб-сервер имеет более новую версию.

Возможно, это связано с тем, что установлены заголовки HTTP Expires/Cache-Control.

http://developer.yahoo.com/performance/rules.html#expires

Я писал об этом здесь:

http://www.codinghorror.com/blog/archives/000932.html

Это не плохой совет, по сути, но это может вызвать огромные проблемы, если вы ошибаетесь. Например, в Microsoft IIS заголовок Expires всегда отключается по умолчанию, вероятно, именно по этой причине. Установив заголовок Expires в ресурсах HTTP, вы сообщаете клиенту, что он никогда не проверяет наличие новых версий этого ресурса - по крайней мере, до истечения срока действия заголовка Expires. Когда я говорю "никогда", я имею в виду - браузер даже не попросит новую версию; он просто предположит, что его кэшированная версия хороша, пока клиент не очистит кеш, или кеш не достигнет даты истечения срока действия. Yahoo отмечает, что они меняют имя файла этих ресурсов, когда они им обновляются.

Все, что вы действительно сохраняете, это стоимость клиента, который пинговал сервер для новой версии и получал 304 не измененный заголовок обратно в общем случае, когда ресурс не изменился. Это не так много накладных расходов.. если вы не Yahoo. Конечно, если у вас есть набор изображений или скриптов, которые почти никогда не меняются, обязательно используйте кеширование клиентов и включите заголовок Cache-Control. Кэширование имеет решающее значение для производительности браузера; каждый веб-разработчик должен иметь глубокое понимание того, как работает кеширование HTTP. Но используйте его только хирургическим, ограниченным образом для тех конкретных папок или файлов, которые могут принести пользу. Для всего остального риск перевешивает выгоду. Это, конечно же, не то, что вы хотите включить в качестве стандартного по умолчанию для всего вашего сайта.., если вам не нравится изменять имена файлов каждый раз, когда изменяется содержимое.

Ответ 3

@Джейсон и Даррен

IE6 обрабатывает что-либо с строкой запроса как незашифрованный. Вы должны найти другой способ получить номер версии в URL-адресе, например, поддельный каталог:

<script src="/js/version/MyScript.js"/>

и просто удалите этот первый уровень каталога после js на стороне сервера перед выполнением запроса.

EDIT: Извините, все; это Squid, а не IE6, который не будет кэшировать строку запроса. Подробнее здесь.

Ответ 4

Я написал сообщение в блоге о том, как мы преодолели эту проблему:

Предотвращение проблем с кешированием JavaScript и CSS в ASP.NET

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

Ответ 5

Я также являюсь методом простого переименования вещей. Это никогда не терпит неудачу, и это довольно легко сделать.

Ответ 6

Ваш веб-сервер отправляет правильные заголовки, чтобы сообщить браузеру, что у него есть новая версия? Я также добавил дату в querystring. т.е. myscripts.js? date = 4/14/2008 12:45:03 (только дата будет закодирована)

Ответ 7

@Darren Проблема с кэшированием произошла как на IIS 6, так и на Apache 2 из коробки. Я не уверен, что правильное разрешение - изменить заголовки ответов HTTP, но вместо этого перейдите на маршрут переименования, описанный в нескольких ответах здесь.

@Chris Хороший совет. Я думал, что подход с строкой запроса был хорошим, но похоже, что уникальный файл или имя каталога необходимо для всех случаев.

Ответ 8

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

  • Выпуск 1: http://www.foo.com/1/js/foo.js
  • Релиз 2: http://www.foo.com/2/js/foo.js

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

Как только вы это сделаете, вы можете использовать заголовки Expires/Cache-Control, которые позволяют клиенту кэшировать ресурсы JS "навсегда", так как путь изменяется с каждой версией, что, по моему мнению, является тем, чем занимался @JasonCohen.

Ответ 9

Некоторые очень полезные методы в здесь, даже если вы не планируете использовать powershell для автоматизации развертывания.

Ответ 10

Для чего это стоит, я увидел deviantART, совершенно большой, обслуживающий их файлы JS как 54504.js. Я только что проверил и посмотрю, что они теперь служат им как v6core.css? -5855446573 v6core_jc.js? 4150339741 и т.д.

Если проблема с строкой запроса поступает с сервера, я полагаю, что вы можете контролировать это более или менее.