Это детали, которые мне удалось откопать. Прежде всего, стоит отметить, что, хотя обычно считается, что JavaScript интерпретируется и запускается на виртуальной машине, в действительности это не так с современными интерпретаторами, которые склонны компилировать исходный код непосредственно в машинный код (за исключением IE).
Хром: двигатель V8
V8 имеет кеш компиляции. Это хранит скомпилированный JavaScript с использованием хэша источника для до 5 сборок мусора. Это означает, что два идентичных фрагмента исходного кода будут совместно использовать запись кэша в памяти независимо от того, как они были включены. Этот кэш не очищается при перезагрузке страниц.
Источник
Обновление - 19/03/2015
Команда Chrome выпустила подробности о своих новых методах потоковой передачи и кэширования JavaScript .
- Скрипт Потоковое
Скрипт потоковой передачи оптимизирует синтаксический анализ файлов JavaScript. [...]
Начиная с версии 41, Chrome анализирует асинхронные и отложенные сценарии в отдельном потоке, как только начинается загрузка. Это означает, что синтаксический анализ может завершиться всего за миллисекунды после завершения загрузки, что приводит к загрузке страниц на 10% быстрее.
- Кэширование кода
Обычно движок V8 компилирует JavaScript-код страницы при каждом посещении, превращая его в инструкции, понятные процессору. Этот скомпилированный код затем отбрасывается, как только пользователь уходит со страницы, так как скомпилированный код сильно зависит от состояния и контекста компьютера во время компиляции.
В Chrome 42 реализован продвинутый метод хранения локальной копии скомпилированного кода, так что, когда пользователь возвращается на страницу, все этапы загрузки, анализа и компиляции могут быть пропущены. При любой загрузке страницы это позволяет Chrome избегать около 40% времени компиляции и экономит драгоценную батарею на мобильных устройствах.
Опера: Каракан Двигатель
На практике это означает, что всякий раз, когда программа сценария собирается скомпилироваться, исходный код которой идентичен исходному коду какой-либо другой программы, которая была недавно скомпилирована, мы повторно используем предыдущий вывод компилятора и полностью пропускаем этап компиляции. Этот кэш достаточно эффективен в типичных сценариях просмотра, когда страница загружается страница за страницей с одного и того же сайта, например, различных новостных статей из службы новостей, поскольку каждая страница часто загружает одну и ту же, иногда очень большую, библиотеку сценариев.
Поэтому JavaScript перезагружается при перезагрузке страницы, два запроса к одному и тому же сценарию не приведут к повторной компиляции.
Источник
Firefox: движок SpiderMonkey
SpiderMonkey использует в Nanojit
качестве своего собственного back-end JIT-компилятор. Процесс компиляции машинного кода можно увидеть здесь . Короче говоря, похоже , что он перекомпилирует скрипты по мере их загрузки. Однако, если мы поближе рассмотрим внутреннее устройство, Nanojit
мы увидим, что монитор более высокого уровня jstracer
, который используется для отслеживания компиляции, может проходить три этапа во время компиляции, обеспечивая преимущество Nanojit
:
Начальное состояние монитора трассировки - мониторинг. Это означает, что spidermonkey интерпретирует байт-код. Каждый раз, когда spidermonkey интерпретирует байт-код обратного перехода, монитор записывает, сколько раз было выполнено переключение значения счетчика целевой программы перехода (ПК). Этот номер называется счетчиком обращений для ПК. Если число попаданий определенного ПК достигает порогового значения, цель считается горячей.
Когда монитор решает, что целевой ПК горячий, он просматривает хеш-таблицу фрагментов, чтобы увидеть, есть ли фрагмент, содержащий нативный код для этого целевого ПК. Если он находит такой фрагмент, он переходит в режим выполнения. В противном случае он переходит в режим записи.
Это означает, что для hot
фрагментов кода нативный код кэшируется. Это означает, что не нужно будет перекомпилировать. Не ясно, что эти хэшированные собственные разделы сохраняются между обновлениями страниц. Но я бы предположил, что они есть. Если кто-то может найти подтверждающие доказательства для этого, то отлично.
EDIT : Это было отмечено, что Mozilla разработчик Борис Збарский заявил , что Gecko не кэш скомпилирована сценарии еще . Взято из этого так ответ .
Safari: JavaScriptCore / SquirelFish Engine
Я думаю, что лучший ответ для этой реализации уже был дан кем-то еще .
В настоящее время мы не кэшируем байт-код (или собственный код). Это
вариант, который мы рассмотрели, однако в настоящее время генерация кода - это
тривиальная часть времени выполнения JS (<2%), поэтому
в данный момент мы не занимаемся этим.
Это написал Мацей Стаховяк , ведущий разработчик Safari. Поэтому я думаю, что мы можем принять это за правду.
Мне не удалось найти какую-либо другую информацию, но вы можете прочитать больше об улучшениях скорости последнего SquirrelFish Extreme
движка здесь или просмотреть исходный код здесь, если вы чувствуете себя в авантюре.
IE: Chakra Engine
В этой области нет текущей информации о JavaScript Engine (Чакра) IE9. Если кто-нибудь что-то знает, пожалуйста, прокомментируйте.
Это вполне неофициальное, но для более старых реализаций двигателя в IE, Эрик Липперто ( разработчик МС JScript ) утверждает в блоге ответа здесь , что:
JScript Classic действует как скомпилированный язык в том смысле, что перед запуском любой программы JScript Classic мы полностью проверяем синтаксис кода, генерируем полное дерево разбора и генерируем байт-код. Затем мы запускаем байт-код через интерпретатор байт-кода. В этом смысле JScript ничуть не менее «скомпилирован», чем Java. Разница в том, что JScript не позволяет вам сохранять или проверять наш проприетарный байт-код . Кроме того, байт-код намного более высокого уровня, чем байт-код JVM - язык байт-кода JScript Classic - это не что иное, как линеаризация дерева разбора, тогда как байт-код JVM явно предназначен для работы на низкоуровневой машине стека.
Это говорит о том, что байт-код не сохраняется никоим образом, и, следовательно, байт-код не кэшируется.