Как обновить кэш javascript

Обновлено: 07.07.2024

Я заметил, что некоторые браузеры (в частности, Firefox и Opera) очень усердно используют кэшированные копии файлов .css и .js даже между сеансами браузера. Это приводит к проблеме при обновлении одного из этих файлов, но браузер пользователя продолжает использовать кэшированную копию.

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

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

Обновить :

После некоторого обсуждения здесь я нашел предложение Джона Милликина и da5id полезным. Оказывается, есть термин для этого: автоматическое управление версиями .

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

Другая идея, предложенная SCdF , заключается в добавлении в файл фиктивной строки запроса. (Некоторый код Python для автоматического использования метки времени в качестве фиктивной строки запроса был представлен пи .). Тем не менее, существует некоторое обсуждение относительно того, будет ли браузер кэшировать файл со строкой запроса. (Помните, мы хотим, чтобы браузер кэшировал файл и использовал его при будущих посещениях. Мы хотим, чтобы он снова извлекал файл только после его изменения.)

Поскольку не ясно, что происходит с фиктивной строкой запроса, я не принимаю этот ответ.

У меня есть это в моей .htaccess, и никогда никаких проблем с кэшированных файлов: ExpiresActive On ExpiresDefault "modification" . Я действительно ценю способ, которым этот вопрос был задан и был обновлен с тех пор. Это полностью описало то, что я должен ожидать в ответах. Я собираюсь следовать этому подходу в моих вопросах отныне. Ура!

Обновление: переписано для включения предложений от Джона Милликина и da5id . Это решение написано на PHP, но должно быть легко адаптировано к другим языкам.

Обновление 2: Включение комментариев Ника Джонсона о том, что оригинальное .htaccess регулярное выражение может вызвать проблемы с такими файлами, как json-1.3.js . Решение состоит в том, чтобы переписать только если в конце есть ровно 10 цифр. (Поскольку 10 цифр охватывают все метки времени с 9.09.2001 по 20.11.22.)

Сначала мы используем следующее правило перезаписи в .htaccess:

Теперь мы напишем следующую функцию PHP:

Теперь, куда бы вы ни включили свой CSS, измените его следующим образом:

Таким образом, вам больше никогда не придется изменять тег ссылки, и пользователь всегда увидит последнюю версию CSS. Браузер сможет кэшировать файл CSS, но когда вы вносите какие-либо изменения в свой CSS, браузер увидит это как новый URL, поэтому он не будет использовать кэшированную копию.

Это также может работать с изображениями, значками и JavaScript. В основном все, что не генерируется динамически.

Мой собственный статический контент-сервер делает то же самое, за исключением того, что я использую параметр для управления версиями (base.css? V = 1221534296) вместо изменения имени файла (base.1221534296.css). Я подозреваю, что ваш путь может быть немного более эффективным, хотя. Очень круто. @Kip: очень удобное решение. Переписывание URL, очевидно, может предложить гораздо больше, чем просто красивые ссылки. Я вижу проблему в том, что она обращается к файловой системе много раз - точно - количество ссылок * количество запросов / сек . что может быть или не быть проблемой для вас. @AlixAxel: Нет, браузеры будут повторно извлекать его при изменении параметра, но некоторые публичные прокси не будут кэшировать файлы с параметрами url, поэтому лучше всего указывать версию в пути. И издержки на mod_rewrite незначительны по сравнению с любыми другими узкими местами производительности в WPO Первая file_exists проверка действительно необходима? filemtime вернет false в случае неудачи, так почему бы просто не присвоить значение filemtime переменной и проверить, является ли оно false перед переименованием файла? Это сократило бы одну ненужную файловую операцию, которая действительно сложилась бы.

Простая клиентская техника

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

Обычные посетители вашего сайта не будут иметь того опыта, который вы испытываете при разработке сайта. Так как среднестатистический посетитель посещает сайт реже (может быть, только несколько раз в месяц, если вы не являетесь сетью Google или hi5), тогда он с меньшей вероятностью будет хранить ваши файлы в кеше, и этого может быть достаточно. Если вы хотите принудительно ввести новую версию в браузер, вы всегда можете добавить строку запроса в запрос и увеличить номер версии при внесении серьезных изменений:

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

С другой стороны, если вы разрабатываете веб-сайт, вы не хотите менять номер версии каждый раз, когда сохраняете изменения в своей версии для разработки. Это было бы утомительно.

Поэтому, пока вы разрабатываете свой сайт, хорошим трюком будет автоматическая генерация параметра строки запроса:

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

Так что, хотите верьте, хотите нет, но на самом деле ваш сервер делает этот кеш браузера таким постоянным. Вы можете настроить параметры сервера и изменить заголовки EXPIRES, но небольшая техника, которую я написал выше, вероятно, намного проще для вас. Поскольку кэширование - это хорошо, обычно вы хотите установить эту дату далеко в будущее («Заголовок истекает в далеком будущем») и использовать метод, описанный выше, для принудительного изменения.

Кэширование кода (также называемое кэшированием байт-кода) является важным инструментом оптимизации. Оно уменьшает время запуска часто посещаемых сайтов за счёт кэширования результатов парсинга и компиляции. Большинство популярных браузеров реализует кэширование в некоторой форме, и Chrome не исключение. О том, как Chrome и V8 кэшируют скомпилированный код, уже много всего написано и сказано.

В этой статье вы найдёте несколько советов JS-разработчикам, которые хотят с помощью кэширования кода улучшить загрузку сайтов. Мы будем говорить о реализации кэширования в Chrome / V8, но большинство советов можно использовать и для кэширования кода других браузеров.

Обзор кэширования кода

Кэш оперативной памяти

У Chrome есть два уровня кэширования скомпилированного в V8 кода (классических скриптов и скриптов модулей): быстрый и «лучший из возможного» кэш в оперативной памяти, обеспечиваемый средствами V8 (кэш Isolate ), а также полный сериализованный кэш на диске.

Кэш Isolate работает со скриптами, скомпилированными в том же V8 Isolate (т. е. тот же процесс, грубо говоря «одни и те же страницы сайта при навигации по одной и той же вкладке»). Это «лучшее из возможного» в том смысле, что кэш оперативной памяти, насколько это возможно, быстр и минимален: он использует уже имеющиеся данные за счёт потенциально более низкой частоты обращений и отсутствия кэширования между процессами.

  • Когда V8 компилирует скрипт, скомпилированный байт-код сохраняется в хеш-таблице (в куче V8), ключ которого определяется исходным кодом сценария.
  • Когда Chrome просит V8 скомпилировать другой скрипт, V8 сначала проверяет, соответствует ли исходный код этого скрипта чему-либо в хеш-таблице. Если соответствует, просто возвращается существующий байт-код.

Этот кэш быстрый и эффективный, но на практике у него лишь 80% частоты попаданий.

Кэш на диске

  1. Когда JS-файл запрашивается впервые (т. е. выполняется «холодный» запуск), Chrome загружает его и даёт V8 для компиляции. Он также сохраняет файл в кэше браузера на диске.
  2. Когда JS-файл запрашивается во второй раз (т. е. выполняется «тёплый» запуск), Chrome берёт файл из кэша браузера и снова передаёт его в V8 для компиляции. Однако на этот раз скомпилированный код сериализуется и прикрепляется к кэшированному файлу скрипта в качестве метаданных.
  3. В третий раз (т. е. «горячий» запуск) Chrome извлекает как файл, так и метаданные файла из кэша и передаёт их в V8. Тот в свою очередь десериализует метаданные и может пропустить компиляцию.

cache

Кэширование кода делится на холодные, тёплые и горячие запуски, используя кэш в оперативной памяти при тёплых запусках и дисковый кэш при горячих запусках.

Основываясь на этом описании, можно оптимизировать использование кэшей кода на вашем сайте.

Совет 1: не делайте ничего

Лучшее, что JS-разработчик может сделать для оптимизации кэширования кода, — ничего не делать. Но ничего не делать можно по-разному: пассивно и активно.

Старт 22 ноября, 4 месяца, Онлайн, От 35 000 до 100 000 ₽

Кэширование кода в конце концов является частью реализации браузера. По сути, это увеличение производительности за счёт дополнительных расходов памяти, реализация и эвристика которых могут постоянно меняться. Мы, как разработчики V8, должны делать всё возможное, чтобы эти эвристики работали для каждого. Если чрезмерно оптимизировать кэширование кода, можно очень разочароваться уже после нескольких релизов, когда эти детали изменятся. Кроме того, другие механизмы JavaScript могут иметь различные эвристики для своей реализации кэширования кода. Так что во многих отношениях лучший совет для получения кэшированного кода похож на совет по написанию JS: пишите чистый идиоматический код и сделайте всё возможное, чтобы оптимизировать его кэширование.

Помимо пассивного бездействия, вы также должны стараться активно «ничего не делать». Любая форма кэширования по своей природе зависит от того, что ничего не меняется, поэтому бездействие — лучший способ сохранить кэшированные данные. Активно ничего не делать можно разными способами.

Не меняйте код

Не меняйте URL’ы

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

Конечно, это также можно использовать для принудительной очистки кэша, хоть это и является частью реализации. Однажды мы можем решить связать кэши с исходным текстом, а не с исходным URL, и этот совет перестанет работать.

Не меняйте поведение выполнения

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

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

В этом случае только A() или B() компилируются и выполняются при «горячем» запуске и вводятся в кэш кода, но любой из них может быть выполнен и в последующих запусках. Вместо этого надо попытаться сохранить выполнение детерминированным, чтобы сохранить его в кэшированном пути.

Совет 2: сделайте что-нибудь

Конечно, совет не делать ничего (пассивно или активно) не очень удовлетворит вас. Помимо того что вы ничего не делаете, учитывая текущую эвристику и реализацию, есть несколько вещей, которые вы можете сделать. Эвристика может измениться, сам этот совет может измениться и нет никакой альтернативы для профилирования.

Отделите библиотеки от кода

Кэширование кода имеет свои особенности: изменения в любой части сценария делают недействительной кэш-память для всего сценария. Если ваш бандл состоит из стабильных и изменяющихся частей в одном скрипте, например библиотеки и бизнес-логики, то изменения в коде бизнес-логики изменяют кэш кода библиотеки.

Вместо этого вы можете отделить код стабильной библиотеки в самостоятельный скрипт и включить его отдельно. Затем код библиотеки может быть кэширован один раз и оставаться в кэше при изменении бизнес-логики.

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

Объедините библиотеки с кодом

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

  • кэш кода не будет включать функции из более ранних скриптов;
  • кэш кода не будет включать в себя лениво скомпилированные функции, вызываемые более поздними скриптами.

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

Одним из решений этой проблемы является объединение библиотек в единый сценарий, таким образом кэширование кода «видит», какие части библиотеки используются. Это полная противоположность совету выше, универсального решения нет. Конечно, не рекомендуется объединять все ваши JS-скрипты в один большой бандл. В целом разделение его на несколько более мелких скриптов будет полезнее (например, множественные сетевые запросы, потоковая компиляция, интерактивность страниц и т. д.).

Используйте преимущество эвристики IIFE

Только те функции, которые скомпилированы к моменту, когда завершится выполнение скрипта, учитываются в кэше, поэтому существует много видов функций, которые не будут кэшироваться, несмотря на выполнение в более поздний момент. Обработчики событий (даже onload() ), цепочки промисов, неиспользуемые библиотечные функции и всё, что лениво компилируется без вызова к моменту, когда </script> виден — всё это остаётся ленивым и не кэшируется.

Один из способов сделать эти функции кэшированными — заставить их компилироваться. Распространённым способом принудительной компиляции является использование эвристики IIFE. IIFE (immediately-invoked function expressions) — это шаблон, в котором функция вызывается сразу после создания:

Так как IIFE вызываются немедленно, большинство движков JavaScript пытаются обнаружить их и немедленно скомпилировать, чтобы избежать затрат на ленивую компиляцию с последующей полной компиляцией. Существуют различные эвристики для раннего обнаружения IIFE (до анализа функции), наиболее распространённой из которых является символ «(» перед ключевым словом function.

Поскольку эта эвристика применяется рано, она запускает компиляцию, даже если функция на самом деле вызывается не сразу:

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

Группируйте небольшие файлы вместе

В Chrome — минимальный размер для кэшей кода, сейчас это 1 КБ исходного кода. Сценарии меньше не кэшируются, так как затраты будут больше выгоды.

Если на вашем сайте много таких небольших сценариев, подсчёт затрат может больше не применяться аналогичным образом. Лучше объединить их так, чтобы они превышали минимальный размер кэширования кода, и получить выгоду от общего сокращения затрат скрипта.

Избегайте встроенных скриптов

Теги скриптов, исходный код которых встроен в HTML, не имеют внешнего исходного файла, с которым они связаны. Поэтому они не могут быть кэшированы с помощью этого механизма. Chrome пытается кэшировать встроенные скрипты, прикрепляя их к ресурсу документа HTML, но эти кэши становятся зависимыми всего документа HTML — он не должен изменяться и разделяться между страницами.

Простые сценарии не стоит встраивать в HTML, лучше выносить их в отдельные файлы.

Используйте кэши сервис-воркера

Сервис-воркер — это механизм, позволяющий вашему коду перехватывать сетевые запросы на ресурсы на вашей странице. Они позволяют вам создавать локальный кэш из некоторых ваших ресурсов и обслуживать ресурс из кэша всякий раз, когда их запрашивают. Это особенно полезно для страниц, которые продолжают работать в offline-режиме вроде PWA.

Воркер добавляет обработчики событий для установки (создание кэша) и извлечения (обслуживание ресурсов).

Эти кэши могут включать в себя кэшированные ресурсы JS. Но поскольку ожидается, что кэши воркеров будут преимущественно использоваться для PWA, для них используется немного другая эвристика по сравнению с обычным «автоматическим» кэшированием в Chrome. Во-первых, они сразу же создают кэш кода при каждом добавлении ресурса JS. Это означает, что кэш доступен уже при второй загрузке (а не только при третьей, как в обычном случае). Во-вторых, генерируется «полный» кэш для этих скриптов — функции больше не компилируются лениво. Всё компилируется и помещается в кэш. Преимущество заключается в быстрой и предсказуемой производительности, без каких-либо зависимостей порядка выполнения, хоть и за счёт увеличения использования памяти. Обратите внимание, что такая эвристика применяется только к кэшам сервисных воркеров, а не к другому использованию Cache API. В настоящее время Cache API вообще не выполняет кэширование кода, когда используется вне сервисных воркеров.

Трассировка

Ни один из советов выше не поможет ускорить работу вашего сайта. К сожалению, информация о кэшировании сейчас не предоставляется в DevTools, поэтому наиболее надёжный способ выяснить, какие из сценариев вашего сайта кэшируются, — использовать чуть более низкий уровень chrome://tracing .

chrome://tracing записывает инструментальные трассировки Chrome в течение некоторого периода времени с такой визуализацией :

tracing

Трассировка записывает поведение всего браузера, включая другие вкладки, окна и расширения, поэтому она лучше всего работает, когда выполняется в чистом профиле пользователя, с отключёнными расширениями и без открытия других вкладок браузера:

При записи вы должны выбрать, какие категории трассировать. В большинстве случаев вы можете просто выбрать набор категорий «Web developer» (Веб-разработчик), но категории можно выбрать и вручную. Важная категория для кэширования кода — v8 .

chrome tracing categories web developer

chrome tracing categories v8

При холодном запуске сценария информация о кэшировании кода отсутствует. Это означает, что сценарий не участвовал в создании или использовании данных кэша.

chrome tracing cold run

chrome tracing warm run

У меня есть внешний файл JavaScript, и в FireFox или Chrome, все ли данные для просмотра очищены, он НЕ будет обновляться, несмотря ни на что. Я полагаю, что что-то произошло, когда я сделал резервную копию своего файла, и я просто добавил «_thedate» в конец имени. Затем Сохранить как вернуться к исходному имени.

Теперь я не могу избавиться от старого JS, несмотря ни на что, если я не изменю имя файла, чего я действительно не хочу делать, или добавлю скрипт на страницу PHP, которая заполняет его.

Кто-нибудь знает решение этого?

Вы уверены, что ссылаетесь на тот же файл, а затем редактируете этот же файл?

В некоторых браузерах вы можете использовать CTRL F5 для принудительного обновления (на ПК). На Mac это Shift Cmd R

Firebug также имеет сетевую вкладку с «Отключить кэш браузера»

Обновление 2020:

Если вы используете Chrome, вы можете нажать и удерживать значок «Обновить» перед адресной строкой, и появится всплывающее окно, и вы можете выбрать «Жесткая перезагрузка» или даже «Очистить кэш и Жесткая перезагрузка» (похоже удаляется в Chrome версии 80.x):

enter image description here

Обновление 2017:

Если вы используете отладчик Google Chrome, он тот же, вы можете перейти в раздел «Сеть» и убедиться в том, что «Отключить кеш (когда открыт DevTools)», в настройках панели отладчика.

Кроме того, когда вы связываете файл JavaScript, используйте

Или v=2 и т. д., когда вы определенно хотите обновить файл. Или вы можете перейти к консоли и выполнить Date.now() и получить метку времени, например 1491313943549 , и использовать

Некоторые инструменты для сборки будут делать это автоматически или могут быть настроены для этого, делая что-то вроде:

Который по сути разорит кеш.

Обратите внимание , что когда вы используете v=2 или t=1491313943549 , или main.742a4952.js , у вас также есть преимущество в том, что для ваших пользователей они определенно получат более новую версию, как хорошо.

Переименуйте ваш файл js во что-то другое временно. Это единственное, что сработало для меня.

У меня была эта проблема, и я решил ее в Chrome, просто отключив кэш: - нажмите F12; - перейти на вкладку Сеть; - Нажмите «Отключить кэш».

Вы на 100% уверены, что ваш браузер даже загружает скрипт? Перейдите на свою страницу в Firefox и используйте консоль в Firebug, чтобы проверить, был ли загружен скрипт или нет.

1. Очистить кэш браузера в инструментах разработчика браузера 2. Вкладка «Под сетью» - выбрать опцию «Отключить кэш» 3. Перезапустить браузер 4. Принудительно перезагрузить файл Js, команда + shift + R в mac Убедитесь, что новая война правильно развернута на стороне сервера.

Я сходил с ума, пытаясь обновить свои js-файлы, и я попробовал все. Затем я проверил заголовок и вспомнил, что использовал Cloudflare!

В Cloudflare вы можете использовать режим dev для отключения прокси.

Немного опоздал на вечеринку, но если вы добавите это в свой html, он не позволит вашему сайту обновить кеш. Загрузка сайта занимает немного больше времени, но в целях отладки он мне нравится. Взято из этого ответа: Как программно очистить кеш браузера?

Как насчет добавления '? 2' к тегу?

Сервер должен вернуть тот же файл с или без '? 2', но браузер должен увидеть его как другой файл и загрузить заново. Вы можете просто изменить эту строку запроса при каждом изменении файла.

Лучший способ обойти кеш браузера - добавить случайное число в путь к файлу js.

Пример в псевдокоде:

Это гарантирует, что ваш браузер всегда перезагружает файл, потому что он думает, что это другой файл из-за случайного числа в URL.

Сервер всегда будет возвращать файл и игнорировать то, что следует после «?».

Решение, которое я использую. Использование firefox
1. с помощью веб-разработчика -> Веб-консоль
2. откройте файл java-скрипта в новой вкладке.
3. Обновите новую вкладку, и вы должны увидеть новый код.
4. Обновите исходную страницу
5. Вы должны увидеть свои изменения.

У меня такая же проблема некоторое время, и мне удалось выяснить . И мой случай был, потому что у меня есть 2 JavaScript с одинаковым именем функции.

[b] Возникли проблемы: [/ b]
В системе с большим количеством обращений нам необходимо кэшировать некоторые статические файлы на клиенте, чтобы уменьшить трафик загрузки и, таким образом, ускорить доступ клиента. Тем не менее, кеш принесет проблему, то есть как обновить клиент вовремя после того, как сервер обновит файл.
[b] Решения: [/ b]
1. Сохраняйте карту файлов js в файле конфигурации;
2. Динамически загрузить файл js с помощью ключа карты js на странице;
3. После внесения изменений в файл js, просто измените номер версии соответствующего js
[b] Пример: [/ b]
1. Сохраните карту файла js в файле конфигурации (config.js) (Примечание: config.js не кэшируется и обновляется каждый раз)

2. Динамически загрузить файл js с помощью ключа карты js на странице;

3. После внесения изменений в файл js просто измените номер версии соответствующего js. Таким образом, поскольку ссылка отличается, измененный js будет загружен снова. Другие js все еще используют js в кэше, потому что ссылка та же.

Интеллектуальная рекомендация

Поверните строку в целые числа

Тема Описание Преобразуйте строку в целое число (реализация функции integer.valueof (строка), но строка не совпадает 0), требуя функции библиотеки, которая нельзя использовать для преобразования целых.

Docker создает репликацию Redis Master-Slave

Centos установить докер быстрый старт докера Создать Dockerfile Поместите файл на сервер Linux, создайте папку / usr / docker / redis и поместите его в этот каталог Выполните следующий код в каталоге .


Установка GateOne на новом CentOS7

Установка GateOne на новом CentOS7 В последнее время исследуются такие инструменты, как WebSSH2, в настоящее время требуется встроить терминал ssh в веб-приложение и найти GateOne. GateOne - это веб-в.


Примечания к исследованию Qt4 (5), QWaitCondition of QThread Learning


Практические занятия: решения проблем системы управления обучением

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

Вам также может понравиться


искробезопасная практика (5) обратный индекс

задний план Поисковые системы обычно создают инвертированный индекс ключевых слов. Ключевое слово - индекс, за которым следуют веб-страницы, содержащие ключевое слово. На этот раз, используя данные мо.


Решение центра тяжести неправильного многоугольника

Справочник статей Во-первых, решение центра тяжести неправильных многоугольников 1.1 Метод расчета треугольника центра тяжести 1.2 Метод расчета площади треугольника 1.3 Метод расчета площади полигона.

Читайте также: