Разве браузер просматривает javascript на каждой загрузке страницы?

Разве браузеры (IE и Firefox) анализируют связанные файлы javascript каждый раз, когда страница обновляется?

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

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

Ответ 1

Это детали, которые я смог выкопать. Стоит прежде всего отметить, что, хотя JavaScript, как правило, считается интерпретированным и выполняется на виртуальной машине, на современных моделях интерпретаторов это не так, как правило, скомпилировать исходный код непосредственно в машинный код (за исключением IE).


Chrome: двигатель V8

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

Source


Обновление - 19/03/2015

Команда Chrome выпустила информацию об их новых методах потоковой передачи и кеширования JavaScript.

  • Script Потоковая передача

Script потоковая оптимизация синтаксического анализа файлов JavaScript. [...]

Начиная с версии 41, Chrome анализирует сценарии асинхронного и отложенного сценариев в отдельном потоке, как только начнется загрузка. Это означает, что после завершения загрузки синтаксический анализ может завершиться всего в миллисекундах и приведет к загрузке страниц на 10% быстрее.

  1. Кэширование кода

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

В Chrome 42 представлен расширенный способ хранения локальной копии скомпилированного кода, так что, когда пользователь вернется на страницу, операции загрузки, разбора и компиляции могут быть пропущены. На всех загружаемых страницах это позволяет Chrome избегать около 40% времени компиляции и экономить драгоценную батарею на мобильных устройствах.


Опера: Carakan Engine

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

Поэтому JavaScript кэшируется через перезагрузку страниц, два запроса к тому же script не приведут к повторной компиляции.

Источник


Firefox: SpiderMonkey Engine

SpiderMonkey использует Nanojit в качестве своего собственного встроенного компилятора JIT. Процесс компиляции машинного кода можно увидеть здесь. Короче говоря, похоже, что они перекомпилируют сценарии по мере их загрузки. Однако, если мы рассмотрим более подробно в интервалах Nanojit, мы видим, что монитор более высокого уровня jstracer, который используется для отслеживания компиляция может перейти через три этапа во время компиляции, обеспечивая преимущество Nanojit:

Мониторинг начального состояния монитора трассировки. Это значит, что spidermonkey интерпретирует байт-код. Каждый раз, когда spidermonkey интерпретирует байт-код обратного перехода, монитор отмечает количество раз, когда значение счетчика программ-счетчиков (ПК) прыгнули к. Это число называется количеством попаданий для ПК. Если удар подсчет определенного ПК достигает порогового значения, целью является считается горячим.

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

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

ИЗМЕНИТЬ: Было указано, что разработчик Mozilla Борис Збарский заявил, что Gecko еще не кэширует скомпилированные скрипты. Взято из этого SO ответ.


Safari: JavaScriptCore/SquirelFish Engine

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

В настоящее время мы не кэшируем байт-код (или собственный код). Это
вариант, который мы рассмотрели, однако, в настоящее время генерация кода - это тривиальная часть времени выполнения JS (< 2%), поэтому мы не проводим поиск это на данный момент.

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

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


IE: Chakra Engine

В этом поле нет текущей информации о IE9 JavaScript Engine (Chakra). Если кто-нибудь знает что-нибудь, прокомментируйте.

Это довольно неофициально, но для более старых версий IE, Eric Lippert (разработчик MS JScript) заявляет в ответе блога здесь, что:

JScript Classic действует как скомпилированный язык в том смысле, что до запуска любой программы JScript Classic мы полностью синтаксически проверяем код, генерируем полное дерево разбора и генерируем байт-код. Затем мы запускаем байт-код через интерпретатор байт-кода. В этом смысле JScript каждый бит "компилируется" как Java. Разница в том, что JScript не позволяет вам сохранять или проверять наш собственный байт-код. Кроме того, байт-код намного выше, чем байт-код JVM. Язык байт-кода JScript Classic - это немного больше, чем линеаризация дерева синтаксического анализа, тогда как байт-код JVM явно предназначен для работы на низкоуровневой стековой машине.

Это говорит о том, что байт-код не сохраняется никоим образом, и поэтому байт-код не кэшируется.

Ответ 2

Opera делает это, как указано в другом ответе. (источник)

Firefox (движок SpiderMonkey) не кэширует байт-код. (источник)

WebKit (Safari, Konqueror) не кэширует байт-код. (источник)

Я не уверен в IE [6/7/8] или V8 (Chrome), я думаю, что IE может сделать какое-то кэширование, а V8 - нет. IE является закрытым исходным кодом, поэтому я не уверен, но в V8 может не иметь смысла кэшировать "скомпилированный" код, так как они скомпилируются прямо в машинный код.

Ответ 3

Насколько мне известно, только Opera кэширует обработанный JavaScript. См. Раздел "Кэшированные скомпилированные программы" здесь.

Ответ 4

Не стоит ничего, что Google Dart явно решает эту проблему с помощью "Снимков" - цель заключается в ускорении времени инициализации и загрузки путем загрузки подготовленная версия кода.

InfoQ имеет хорошую запись @http://www.infoq.com/articles/google-dart

Ответ 5

Я думаю, что правильный ответ будет "не всегда". Насколько я понимаю, как браузер, так и сервер играют определенную роль в определении того, что кэшируется. Если вам действительно нужны файлы, которые нужно перезагружать каждый раз, то я думаю, вы должны быть в состоянии настроить это из Apache (например). Конечно, я полагаю, что пользовательский браузер может быть настроен так, чтобы игнорировать этот параметр, но это, вероятно, маловероятно.

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

Ответ 6

Браузер определенно использует кеширование, но да, браузеры анализируют JavaScript каждый раз, когда страница обновляется. Поскольку всякий раз, когда страница загружается браузером, она создает 2 дерева Дерево 1.Content и Дерево 2.render.

Это дерево рендеринга состоит из информации о визуальной компоновке элементов dom. Поэтому всякий раз, когда страница загружается, javascript анализируется, и любые динамические изменения javascript будут позиционировать элемент dom, элемент show/hide, add/remove приведет к тому, что браузер заново создаст дерево рендеринга. Но современные броузеры, такие как FF и chrome, обрабатывают его несколько иначе, у них есть концепция инкрементного рендеринга, поэтому всякий раз, когда в js упоминаются динамические изменения, это приведет к тому, что эти элементы будут отображать и снова перерисовывать.