Ответ 1
Это детали, которые я смог выкопать. Стоит прежде всего отметить, что, хотя JavaScript, как правило, считается интерпретированным и выполняется на виртуальной машине, на современных моделях интерпретаторов это не так, как правило, скомпилировать исходный код непосредственно в машинный код (за исключением IE).
Chrome: двигатель V8
V8 имеет кэш компиляции. Это хранит скомпилированный JavaScript с использованием хэша источника для 5 сборников мусора. Это означает, что две идентичные части исходного кода будут совместно использовать запись в кеше в памяти независимо от того, как они были включены. Этот кеш не очищается при перезагрузке страниц.
Обновление - 19/03/2015
Команда Chrome выпустила информацию об их новых методах потоковой передачи и кеширования JavaScript.
- Script Потоковая передача
Script потоковая оптимизация синтаксического анализа файлов JavaScript. [...]
Начиная с версии 41, Chrome анализирует сценарии асинхронного и отложенного сценариев в отдельном потоке, как только начнется загрузка. Это означает, что после завершения загрузки синтаксический анализ может завершиться всего в миллисекундах и приведет к загрузке страниц на 10% быстрее.
- Кэширование кода
Обычно двигатель 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 явно предназначен для работы на низкоуровневой стековой машине.
Это говорит о том, что байт-код не сохраняется никоим образом, и поэтому байт-код не кэшируется.