Чтобы ответить на ваш вопрос, вы должны понять внутреннюю работу языка Javascript через его историю и последние события.
JavaScript определяется как интерпретируемый язык, но также скомпилированный на лету (JIT-Compiled).
Путаница еще больше усугубляется отсутствием информации в самой спецификации JavaScript.
Когда JavaScript выполняется, движок JavaScript браузера (V8 на Chrome, SpiderMonkey на Firefox) или сервер (V8 с Node.js) должны преобразовать исходный код в формат, понятный компьютеру.
Для этого есть два способа: интерпретация или компиляция исходного кода.
Интерпретация : Программа переведена на компьютер язык во время его исполнения (runtime). Каждая строка обрабатывается на лету, не ожидая стадии предварительной обработки.
С другой стороны, когда строка кода выполняется N раз (например, oop), интерпретатор должен повторять перевод машинного языка N раз.
Компиляция : Требуется предварительная фаза перевода на машинный язык для возможности выполнения. Весь код предварительно компилируется и оптимизируется компилятором, чтобы программа могла быть выполнена. Это услуга за услугу, чтобы облегчить проблему, связанную с упомянутыми выше переводчиками.
Появившись в середине 90-х, JavaScript использовался мало, мы нашли некоторые инструкции в теге и призываем к такие функции, как onclick или alert.
Интерпретация была намного проще и обеспечивала совершенно адекватную производительность для случаев использования времени.
В 2000-х годах гонка за производительностью веб-браузеров разгорелась до Дело в том, что это называлось Войной Браузеров. Это период, в течение которого основные веб-игроки (Mozilla, Google) пытаются максимально оптимизировать свой браузер.
Таким образом, Firefox представляет SpiderMonkey, самый первый JIT-компилятор, который позволил увеличить производительность примерно От 20 до 40% по сравнению со старой версией механизма JavaScript.
В ходе этого процесса Google сделал доступным браузер Chrome и его механизм исполнения V8, включая этап компиляции. Последний часто называют «Just in Time» или JIT.
Другие браузеры (Edge, et c.) Также изменили свой движок JavaScript, добавив фазу компиляции. Эта разработка повысила скорость JavaScript в 10 раз и стала рычагом ее использования на ранее немыслимых платформах, таких как серверное программирование (Node.js).
«Как раз вовремя» и компиляция
JIT-компилятор сочетает в себе скорость выполнения интерпретатора с оптимизацией, предоставляемой компилятором.
JavaScript движки, включая JIT, очень часто состоит из 4 основных строительных блоков:
Монитор (профилировщик), который играет роль проводника. Интерпретатор, который выполняет исходный код (время выполнения). Так называемый "basi c". Компилятор, который выполняет некоторые базовые c оптимизации. Компилятор, называемый «оптимизатором», позаботится о дальнейшей оптимизации в случае необходимости.
(упрощенный) процесс выполнения выглядит следующим образом:
1) Монитор вызывает переводчика для выполнения кода. Он на лету анализирует выполненные вызовы функций.
2) Если переводчик делает несколько вызовов одной и той же функции, монитор «помечает» ее как «горячую» функцию.
3) Как как только функция нагревается, монитор связывается с базовым компилятором, чтобы указать, что функция часто используется и что она должна быть скомпилирована.
4) Базовый компилятор выполняет некоторые оптимизации, генерируя оптимизированную версию (заглушка). ) каждой инструкции.
5) Если функция становится все более горячей, она помечается как горячая: ее необходимо дополнительно оптимизировать.
6) Затем монитор решает отправить эту функцию компилятору-оптимизатору, который создаст еще более оптимизированную версию, чем сгенерированный базовым компилятором.
7) Этот компилятор делает несколько предположений относительно этой функции Например, тип переменных. Зная, что JavaScript имеет динамическую c типизацию, вероятность ошибки не равна нулю. Компилятор может удалить свою оптимизацию и ссылаться только на версию, скомпилированную на шаге 4: это операция де-оптимизации.
8) Интерпретатор, которому вместо того, чтобы заново переводить функцию на машинный язык, будет напрямую использовать свою скомпилированную или оптимизированную версию для ускорения обработки.
Этап № 7 подвержен проблемам с производительностью. Действительно, де-оптимизация может замедлить процесс в том случае, если компилятор тратит свое время на оптимизацию, а затем де-оптимизацию кода. Вот почему некоторые JavaScript движки имеют ограничение цикла оптимизации.
Как только этот порог достигнут, компилятор перестанет пытаться оптимизировать и будет ссылаться на версию исходного кода в своем «сыром» виде. форма (та, что на шаге 1) или заглушка, созданная на шаге 4.
Уровень производительности и не вдаваясь в подробности каждого JavaScript двигателя для простоты, мы можем видеть, что он качается: V8 всегда в ведущий и показывает интересные исполнения.
Интерпретировано или скомпилировано?
Теперь, когда у нас есть общее представление о процессе выполнения, мы можем рискнуть пометить JavaScript как интерпретировано или скомпилировано.
JIT-компиляторы переводят исходный код (на машинном языке) на лету, и только для улучшения производительности, это не инициатива, определяющая c для ECMA TC39 или JavaScript.
JavaScript, следовательно, является интерпретируемым языком, который по мере использования и развития должен был сталкиваться с проблемами производительности и приводил к некоторому « гибридный »режим, смешивание интерпретации и компиляции.
Недавно Mozilla предложила эволюцию своего механизма исполнения (HolyJIT) с использованием языка Rust, направленную на повышение производительности и безопасности процесса компиляции.
В конце февраля 2017 года 4 основных браузера (Chrome, Safari, Edge и Firefox) объявили, что MVP (Miminum ценный продукт) в отношении WebAssembly (WASM) был завершен.
Это пьедестал, связанный с JIT-компиляторами, открывает поле возможностей, касающихся использования языков, отличных от JavaScript (C ++, Rust) в браузере.
Например модуль, разработанный на таком языке, как C или Rust, может быть встроен и использован в приложении JavaScript без влияния на браузер.
Все это не тривиально и требует, чтобы код был скомпилирован с помощью для этой цели предусмотрен компилятор, поэтому в качестве выходного файла создается файл .wasm.
Это интересная технология. Нужно следовать нологии, потому что тяжелая обработка (интенсивные вычисления через CPU или GPU) вполне может быть разработана на адаптированном языке (C или C ++), а остальная часть приложения разработана в JavaScript.
Вот несколько интересных статей, они более подробно затрагивают тему: V 110:
http://www.jayconrod.com/posts/54/a-tour-of-v8-crankshaft-the-optimizing-compiler
https://v8project.blogspot.fr/2016/08/firing-up-ignition-interpreter.html
http://www.jayconrod.com/posts/51/a-tour-of-v8-full-compiler
https://ponyfoo.com/articles/an-introduction-to-speculative-optimization-in-v8
https://v8project.blogspot.fr/2017/11/csa.html