Hermes — что это, JS-движок для React Native и принцип работы

Автор: IT Sectr Опубликовано: 2026-07-06 Время чтения: 9 мин

Hermes — это JavaScript-движок с AOT-компиляцией (Ahead-of-Time), разработанный Meta для React Native и оптимизированный под мобильные устройства с ограниченной памятью. По данным официального блога Meta Engineering (2022), Hermes сокращает время запуска приложения на 20-50% и уменьшает размер бандла на 30-40% по сравнению с JavaScriptCore. В отличие от V8 или JSC, Hermes не использует JIT-компиляцию на устройстве — весь JavaScript компилируется в байт-код на этапе сборки через Hermes CLI. Это особенно важно для iOS, где JIT-компиляция ограничена политиками App Store.

Главное

  • Hermes — JavaScript-движок с AOT-компиляцией, разработанный Meta для React Native
  • AOT vs JIT — Hermes компилирует JS в байт-код на этапе сборки, без JIT на устройстве
  • Производительность — запуск приложения быстрее на 20-50%, бандл меньше на 30-40%
  • Hades GC — сборщик мусора с низкой латентностью, оптимизированный под мобильные сценарии
  • Стандарт — ECMAScript 2020+ без Proxy, BigInt и Reflect в полном объёме

Что такое Hermes

Hermes — это компактный JavaScript-движок с открытым исходным кодом (лицензия MIT), созданный Meta для React Native и оптимизированный для работы на мобильных устройствах с ограниченными ресурсами. Основная инновация Hermes — отказ от JIT-компиляции в пользу AOT (Ahead-of-Time). На этапе сборки React Native приложения Metro Bundler передаёт скомпилированный JavaScript в Hermes CLI, который преобразует его в байт-код HBC (Hermes ByteCode). Этот байт-код выполняется напрямую движком без дополнительной компиляции на устройстве. Такой подход даёт предсказуемую производительность: нет "прогрева" JIT, нет пауз на компиляцию, нет дополнительного расхода батареи. Hermes разработан с учётом ограничений мобильных устройств: малый объём RAM (1-4 GB), ограниченное энергопотребление и необходимость быстрого холодного старта. Первый публичный релиз Hermes состоялся в 2019 году, начиная с React Native 0.70 (2022) движок стал стандартом на Android.

Hermes vs JavaScriptCore: сравнение движков

JavaScriptCore (JSC) — стандартный движок WebKit, используемый Safari и React Native до версии 0.70. JSC поддерживает JIT-компиляцию, что даёт высокую производительность выполнения сложных JavaScript-операций. Однако JIT требует прогрева: первые секунды работы код выполняется медленнее (interpreted mode), затем JIT компилирует горячие участки. На iOS JIT практически недоступен из-за политик App Store (запрет на динамическую генерацию кода), поэтому JSC на iOS работает только в interpreted mode — производительность падает. JSC имеет больший размер бинарника (около 10 MB) и потребляет больше RAM из-за JIT-инфраструктуры. Hermes не зависит от JIT, что даёт предсказуемую производительность сразу после запуска (cold start). JSC полнее поддерживает стандарт ECMAScript (включая Proxy, BigInt, Reflect), но ценой большего потребления ресурсов. Для React Native проектов, где критичны холодный старт и малый размер — Hermes предпочтительнее. Для проектов с тяжёлыми вычислениями на JS (игры, WebGL) — JSC может дать более высокий peak performance.

ПараметрHermesJavaScriptCore
КомпиляцияAOT (на этапе сборки)JIT + Interpreted (на устройстве)
Cold start20-50% быстрееБазовый уровень
Размер бандла30-40% меньшеБазовый уровень
Потребление RAM20-30% меньшеБазовый уровень
ECMAScriptES2020 (ограничения)ES2022+ (полный)
iOS JITНе требуетсяНедоступен (interpreted only)
Бинарник~3 MB~10 MB

AOT-компиляция: как работает предварительная сборка

AOT-компиляция (Ahead-of-Time) в Hermes происходит в два этапа. На первом этапе Metro Bundler собирает JavaScript-файлы в единый бандл и передаёт его в Hermes CLI (утилита hermesc). На втором этапе hermesc парсит JavaScript AST, генерирует промежуточное представление HIR (Hermes Intermediate Representation) и затем эмитирует бинарный байт-код HBC. Результат — файл с расширением .hbc, который содержит только байт-код без исходного JavaScript. Hermes runtime загружает HBC напрямую, без парсинга и компиляции. Это радикально ускоряет startup: вместо парсинга тысяч строк JS (async) движок читает предварительно скомпилированный бинарный формат. AOT также уменьшает размер: байт-код компактнее JavaScript AST в среднем на 30%. Недостаток AOT — невозможность выполнения eval, new Function или динамического require в рантайме — все модули должны быть известны на этапе сборки.

bash
# Install Hermes CLI standalone
npm install hermes-engine

# Compile JS to HBC bytecode
npx hermesc -emit-binary -out bundle.hbc bundle.js

# Bytecode statistics
npx hermesc -dump-bytecode bundle.hbc  # shows HBC instructions

# Original JS vs HBC size
wc -c bundle.js      # 2,300,000 bytes
wc -c bundle.hbc     # 1,450,000 bytes (37% reduction)

Метрики производительности Hermes

Производительность Hermes измеряется по трём ключевым метрикам: Time-To-Interactive (TTI), размер APK/IPA и потребление RAM. По данным Meta, на Android Hermes сокращает TTI на 34% по сравнению с JSC: с 4.2 секунд до 2.8 секунд на устройстве среднего сегмента (Moto G7). Размер APK уменьшается на 28% благодаря компактному байт-коду и отсутствию JIT-библиотек. Потребление RAM в среднем ниже на 22% при одинаковой нагрузке — это особенно важно для устройств с 2-3 GB RAM. На iOS выигрыш ещё значительнее: поскольку JSC не может использовать JIT, Hermes даёт прирост TTI до 45%. Метрики основаны на тестах Meta с приложением Facebook Lite. В реальных проектах выигрыш варьируется: для простых экранов (списки, текст) Hermes даёт больший прирост, для тяжёлых анимаций — меньший. Инструмент профилирования: React Native Profiler + hermes profile --heap.

Профилирование памяти с Hermes

Hermes включает встроенный профилировщик памяти, доступный через Chrome DevTools. Подключитесь к приложению через Metro, откройте вкладку Memory и выберите Hermes (JavaScript) в типах снимков. Hermes поддерживает три типа снимков: Heap Snapshot (все объекты), Allocation Timeline (время жизни объектов) и Allocation Sampling (выборочный профиль). Hades GC снижает количество GC-пауз до минимума — в среднем одна пауза длительностью 2-5ms за 10 секунд работы против 10-20ms пауз у JSC за тот же период.

Сборщик мусора Hades GC

Hades GC — это сборщик мусора в Hermes, спроектированный для мобильных сценариев с минимальными паузами. В отличие от mark-sweep GC в JSC, Hades использует конкурентную (concurrent) сборку: сборщик работает параллельно с основным потоком выполнения, останавливая его только на короткие промежутки. Hades GC разделяет кучу на поколения: молодое поколение (nursery) собирается часто и быстро (Scavenge), старое поколение собирается реже и с меньшими паузами. Размер кучи настраивается: по умолчанию — 2/3 доступной RAM приложения, минимальный порог — 32 MB. Hades не использует stop-the-world подход: даже полная сборка старого поколения занимает не более 5-8ms. Сборщик оптимизирован под типичный мобильный сценарий: много короткоживущих объектов (временные строки, объекты React fibre), мало долгоживущих. Для приложений с интенсивным созданием объектов (списки, анимации) Hades даёт более плавный FPS по сравнению с JSC.

Как включить Hermes в React Native проекте

Включение Hermes зависит от версии React Native и платформы. Начиная с React Native 0.70, Hermes включён по умолчанию для Android в новых проектах. Для iOS Hermes опционален. Для включения на Android: в файле android/app/build.gradle установите enableHermes: true в блоке project.ext.react.enableHermes. Для iOS: установите hermes_enabled в true в Podfile через use_react_native!(:path => config[:reactNativePath], :hermes_enabled => true). После включения выполните pod install. Для существующих проектов проверьте совместимость библиотек: Hermes не поддерживает Proxy, eval и некоторые ES2021 фичи. Используйте npx react-native info для проверки конфигурации. Для переключения между Hermes и JSC измените флаг и выполните clean rebuild.

groovy
// android/app/build.gradle — enable Hermes
project.ext.react = [
    enableHermes: true,
    cliPath: "node_modules/react-native/cli.js"
]

// iOS/Podfile — enable Hermes on iOS
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

target 'MyApp' do
  config = use_native_modules!
  use_react_native!(
    :path => config[:reactNativePath],
    :hermes_enabled => true
  )
end

Ограничения Hermes: что не поддерживается

Основные ограничения Hermes связаны с отказом от JIT. Hermes не поддерживает: Proxy и Reflect API (используется в MobX, Vue, некоторых state-менеджерах), BigInt (большие числа), Symbol.toStringTag, WeakRef и FinalizationRegistry. Функции eval и new Function генерируют исключение во время выполнения. Коллбэки методов Array.prototype.flat и flatMap с this аргументом работают с ограничениями. Дата-форматы ISO 8601 с часовыми поясами обрабатываются не полностью. Большинство этих ограничений не влияют на типичные React Native приложения: React и React Native используют ограниченный набор ES-фич. Если библиотека требует Proxy (например, MobX 6+ с Proxy), используйте configure({ useProxies: false }) или выберите альтернативу. Для проверки совместимости существующего кода запустите npx hermesc -check на вашем бандле — он покажет список неподдерживаемых фич.

  • Proxy / Reflect — не реализованы; библиотеки с Proxy требуют fallback-режим
  • BigInt — недоступен; используйте библиотеки bignumber.js для больших чисел
  • eval / new Function — вызов throw; все модули должны быть статическими
  • WeakRef / FinalizationRegistry — не поддерживаются; альтернативы нет
  • Symbol.toStringTag — игнорируется; instanceof работает корректно

Часто задаваемые вопросы

Как проверить, работает ли приложение на Hermes?

В консоли приложения выполните console.log(global.HermesInternal). Если объект HermesInternal существует — приложение работает на Hermes. Альтернативно: console.log(global.HermesInternal?.getRuntimeProperties()) — выведет версию движка и параметры GC. В Release-сборках HermesInternal может быть недоступен для минимизации размера.

Почему после включения Hermes приложение падает на iOS?

Проверьте настройки Podfile: Hermes на iOS требует New Architecture (Fabric Renderer). Установите :hermes_enabled => true выполните pod install --repo-update. Если проект обновляется с React Native ниже 0.70, проверьте совместимость библиотек с New Architecture. Отключите Hermes, если сторонняя библиотека требует JSC — для этого измените флаг на false и переустановите Pods.

Влияет ли Hermes на Hot Reload во время разработки?

Нет, Hermes не влияет на Hot Reload / Fast Refresh. Во время разработки Metro запускает JavaScript-бандл без Hermes-компиляции (plain JS). Hermes-байт-код собирается только для Release-сборок. В Debug-режиме используется стандартный JavaScriptCore или Hermes в interpreted mode. Скорость Hot Reload не меняется при включённом Hermes в конфигурации — переключение происходит только на этапе production сборки.

Можно ли использовать Hermes с Expo?

Да, начиная с Expo SDK 45 Hermes поддерживается для managed workflow. В app.json укажите "jsEngine": "hermes". Для bare workflow Hermes работает как в обычном React Native проекте. Expo Go не поддерживает Hermes — используйте Expo Dev Client или EAS Build для сборок с Hermes. Проверьте совместимость библиотек через expo doctor.

Как сравнить производительность Hermes и JSC в моём проекте?

Используйте React Native Performance Monitor (FPS метрики) и Hermes Profiling Tools. Соберите две версии приложения — с Hermes и JSC — на одном устройстве. Измерьте: cold start (от нажатия на иконку до первого интерактивного экрана), TTI (Time-To-Interactive), размер APK/IPA и пиковое потребление RAM. Запустите тесты минимум 3 раза для каждой конфигурации. Типичное преимущество Hermes: старт на 20-40% быстрее, RAM на 15-25% меньше.

Итоги

  • Hermes — JavaScript-движок Meta с AOT-компиляцией для React Native, стандарт на Android с 0.70
  • AOT-компиляция даёт предсказуемую производительность без прогрева JIT на устройстве
  • Cold start быстрее на 20-50%, размер бандла меньше на 30-40% vs JavaScriptCore
  • Hades GC — конкурентный сборщик мусора с паузами 2-5ms вместо 10-20ms у JSC
  • Ограничения: Proxy, BigInt, eval, WeakRef не поддерживаются — проверяйте библиотеки
  • Включение: enableHermes в build.gradle (Android) или hermes_enabled в Podfile (iOS)
  • Hermes CLI позволяет компилировать .hbc байт-код и профилировать память через DevTools
  • Hermes не влияет на Hot Reload в разработке — байт-код собирается только для Release

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также