awesome-everything EN
↑ Обратно к восхождению

Браузер и фронтенд-рантайм

Что такое V8 и почему производительность различается в 100 раз

Суть V8 преобразует JS-код в машинный через четыре уровня компиляции — одна и та же функция может работать в 100 раз быстрее или медленнее в зависимости от того, удаётся ли V8 удержать её на быстром уровне.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на junior-высоте — поверхность
◷ 10 min

React рендерит 1000 строк. При стабильных формах объектов — наносекундные поиски и 60fps. При смешанных формах — в 10–50 раз медленнее, тот же код, та же функция, разная скорость из-за того, что V8 наблюдал.

Что такое V8

V8 — это движок JavaScript внутри Chrome, Edge и Node.js. Он берёт исходный JS-код и преобразует его в машинный код, который выполняет CPU. Одна и та же JS-функция может работать в 100 раз быстрее или медленнее в зависимости от того, может ли V8 её оптимизировать. Несколько привычек — стабильные формы объектов, мономорфные точки вызова — решают разницу между анимацией на 60fps и тормозящей страницей.

Метафора кухни

V8 — это кухня с четырьмя поварами:

  • Стажёр (Ignition) читает каждый рецепт медленно, но записывает, что заказывали.
  • Линейный повар (Sparkplug) быстро выдаёт универсальные блюда.
  • Су-шеф (Maglev) делает специализированные версии популярных блюд.
  • Шеф-повар (TurboFan) вручную создаёт идеальное блюдо для самого популярного заказа — но только если заказы остаются стабильными. Измените заказ на полуслове — и TurboFan выбросит блюдо.
Уровни V8 в кратком обзоре
Уровни
4 (Ignition / Sparkplug / Maglev / TurboFan)
Ignition vs TurboFan скорость
~100× медленнее
Замедление при megamorphic
10–50× vs monomorphic
IC monomorphic доступ
5–10 тактов CPU

Конкретный разбор

Антон · Браузер запускает JS в браузере. Ignition сначала интерпретирует, записывая типы. После тысяч вызовов V8 продвигает код в TurboFan с предположениями «аргумент всегда число, объект всегда имеет .x». Если Дима · Origin-сервер однажды пришлёт строку, предположения нарушатся — deopt, откат. «Быстрая» функция снова медленная, пока V8 не переобучится.

React рендерит 1000 строк. Стабильные ключи = monomorphic IC, наносекундные поиски. Смешанные ключи = polymorphic, в 2–3 раза медленнее. 10+ форм = megamorphic, в 10–50 раз медленнее. Тот же код, кардинально разная скорость.

Расставь шаги по порядку

Упорядочите путь горячей функции через уровни V8:

  1. 1 JS-источник разбирается в AST
  2. 2 AST преобразуется в байткод компилятором Ignition
  3. 3 Ignition интерпретирует байткод и записывает type feedback на каждую точку вызова
  4. 4 После тысяч вызовов Sparkplug генерирует базовый машинный код без специализации
  5. 5 При дальнейшем нагреве Maglev компилирует оптимизированную версию среднего уровня
  6. 6 Для самых горячих путей TurboFan выполняет агрессивную спекулятивную оптимизацию
  7. 7 При нарушении предположения V8 выполняет deopt и откатывается на нижний уровень
Викторина

Почему V8 использует несколько уровней компиляции вместо одного?

Викторина

Что делает один фрагмент JS в 100 раз быстрее другого, делающего «то же самое»?

Закончи аналогию

Заполните пробел: точка вызова, которая видела ровно одну форму объекта, называется _______, и V8 генерирует для неё максимально быстрый машинный код.

Почему это работает

Зачем движку динамического языка знать типы? Машинный код типизирован — инструкция ADD для целых отличается от инструкции для чисел с плавающей точкой. V8 наблюдает, какие типы реально видит точка вызова, и генерирует специализированный код для этих типов. При изменении типа во время выполнения V8 должен выбросить специализированный код и начать заново. Это и есть цена deopt.

Вспомните перед уходом
  1. 01
    Назовите четыре уровня компиляции V8 по порядку от самого медленного к самому быстрому.
  2. 02
    Почему добавление нового свойства к объекту в середине кода замедляет последующие функции?
  3. 03
    Что такое monomorphic inline cache и почему это самое быстрое состояние IC?
Итог

V8 — движок JS в Chrome и Node.js. Код выполняется через четыре уровня: Ignition интерпретирует медленно, собирая type feedback; Sparkplug генерирует дешёвый базовый машинный код; Maglev оптимизирует с наблюдаемыми типами; TurboFan создаёт агрессивно оптимизированный код для самых горячих функций. Функция остаётся на быстром уровне только пока формы объектов — hidden classes — остаются стабильными. Одно лишнее свойство в неподходящий момент меняет hidden class, деградирует inline cache с monomorphic до polymorphic или megamorphic и обходится в 10–50 раз дороже на этой точке вызова. Одна и та же JS-функция может работать за 5 тактов или за 500 тактов на доступ к свойству в зависимости от стабильности форм.

Связанные уроки
встречается в143
Продолжить восхождение ↑Четырёхуровневый JIT-конвейер V8 и профилированная тиеризация
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.