Пока CSS разбирается и создается CSSOM, загружаются другие активы, включая файлы JavaScript. Это происходит благодаря preloader
, о котором мы упоминали в предыдущих статьях.
A preloader is like a parser that scans the HTML file while the main parser is processing the HTML code. Its role is to look for resources like stylesheets, scripts or images (that also need to be retrieved from a server) and request them. Hopefully, by the time the HTML is parsed, those resources are already downloaded and ready to be processed.
5. ВЫПОЛНЕНИЕ JAVASCRIPT
Итак, после того как мы получаем файл Javascript с сервера, код интерпретируется, компилируется, разбирается и выполняется. Компьютер не может понять код Javascript, это может сделать только браузер. JS-код должен быть переведен во что-то, с чем компьютер может работать, и это работа Javascript-движка браузера
(не путать с движком браузера
). В зависимости от браузера, движки JS могут иметь разные названия и работать по-разному.
Движки Javascript
Движок javascript (иногда также называемый ECMAScript engine
) – это часть программного обеспечения, которая исполняет (запускает) код Javascript в браузере, и не только (например, движок V8 является основным компонентом среды Node.js).
Движки JavaScript обычно разрабатываются производителями браузеров, и каждый крупный браузер имеет такой движок. Мы сказали, что наиболее используемыми браузерами на сегодняшний день являются Chrome
, Safari
, Edge
и Firefox
. Каждый из них использует свой движок Javascript, а именно:
V8
V8 – это высокопроизводительный движок JavaScript от Google. Он написан на C++ и используется, в частности, в Chrome и Node.js. Он реализует ECMAScript
(стандарт JavaScript, предназначенный для обеспечения совместимости веб-страниц в различных браузерах) и WebAssembley
. Он реализует стандарт ECMA-262.
JavaScriptCore
JavaScriptCore – это встроенный JavaScript-движок для WebKit, на котором работают браузер Safari, Mail и другие приложения, используемые в macOS. В настоящее время он реализует ECMAScript в соответствии со спецификацией ECMA-262. Также он называется SquirrelFish
или SquirrelFish Extreme
.
Chakra
Chakra – это движок Javascript, разработанный компанией Microsoft для своего веб-браузера Microsoft Edge и других приложений Windows. Он реализует ECMAScript 5.1 и имеет частичную (растущую) поддержку ECMAScript 6. Он написан на C++.
SpiderMonkey
SpiderMonkey – это движок Mozilla для работы с Javascript и WebAssembly Engine. Он написан на C++, Javascript и Rust и используется для работы Firefox, Servo и других проектов.
Вначале движки Javascript были простыми интерпретаторами. Современные браузеры, которыми мы пользуемся сегодня, способны выполнять так называемую Just-In-Time (JIT) компиляцию
, представляющую собой смесь между компиляцией
и интерпретацией
.
Компиляция
Во время компиляции часть программного обеспечения, называемая компилятор
, берет код, написанный на языке высокого уровня, и преобразует его в машинный код, причем все сразу. Создается промежуточный файл (называемый объектным файлом
), который может работать на любой машине. После выполнения этих действий код может быть выполнен (сразу после, иногда в будущем или никогда).
Интерпретация
Во время интерпретации интерпретатор просматривает код Javascript строка за строкой и сразу же выполняет его. Компиляции не происходит, поэтому объектный код не создается (вывод кода создается самим интерпретатором, используя его внутренние механизмы). Более старые версии Javascript используют этот тип выполнения кода.
JIT-компиляция
Очень важным аспектом JIT-компиляции является то, что она компилирует исходный код в инструкции машинного кода работающей машины. Это означает, что полученный машинный код оптимизирован под архитектуру процессора работающей машины.
В очень простых терминах эти три процесса можно представить следующим образом:
- Компилятор: переводит код
- Интерпретатор: выполняет код
- JIT-компилятор: переводит код во время его выполнения.
Сегодня грань между терминами компиляция
и интерпретация
стала очень размытой, поэтому этот вопрос может вызывать много споров. Если вы хотите узнать больше об этих процессах, то для начала можете прочитать эту статью на Mozilla Hacks.
Обратите внимание, что я упомянул старые и новые версии Javascript. Браузеры, которые не поддерживают новые версии языка, будут интерпретировать код, а те, которые поддерживают, будут использовать некоторую версию JIT для выполнения кода (движки V8, Chakra JavaScriptCore и SpiderMonkey все используют JIT). Правда в том, что хотя Javascript является интерпретируемым языком (ему не нужна компиляция), большинство браузеров сегодня используют JIT-компиляцию для выполнения кода, вместо чистой интерпретации.
Как обрабатывается код Javascript
Когда код Javascript попадает в движок Javascript, на первом этапе он подвергается разбору. Это означает, что код читается, и в это время код преобразуется в структуру данных, называемую Abstract Syntax Tree
(AST). Код будет разделен на части, которые имеют отношение к языку (например, ключевые слова function
или const
), а затем все эти части построят Абстрактное Синтаксическое Дерево.
Допустим, у нас есть файл, содержащий программу, которая делает только одну вещь, а именно определяет переменную:
const age = 25;
Вот как эта невероятно простая строка кода будет выглядеть в виде дерева абстрактного синтаксиса (я использую @babel/parser-7.16.12):
Если вы хотите самостоятельно преобразовать какой-нибудь Javascript в абстрактное синтаксическое дерево, вы можете воспользоваться этим инструментом. AST, полученное после написания моего варианта, на самом деле гораздо больше и имеет больше узлов, которые скрыты на снимке экрана.
После того, как AST построено, оно переводится в машинный код и сразу же выполняется, поскольку современный Javascript использует компиляцию Just-In-Time. Выполнение этого кода будет осуществляться движком Javascript, используя то, что называется “стек вызовов”.
A call stack is a mechanism for an interpreter (like the JavaScript interpreter in a web browser) to keep track of its place in a script that calls multiple functions — what function is currently being run and what functions are called from within that function etc.
Справочные материалы:
- SpiderMonkey
- ChakraCore
- JavaScriptCore
- v8
- Node
- MDN