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-движок с открытым исходным кодом (лицензия 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.
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.
| Параметр | Hermes | JavaScriptCore |
|---|---|---|
| Компиляция | AOT (на этапе сборки) | JIT + Interpreted (на устройстве) |
| Cold start | 20-50% быстрее | Базовый уровень |
| Размер бандла | 30-40% меньше | Базовый уровень |
| Потребление RAM | 20-30% меньше | Базовый уровень |
| ECMAScript | ES2020 (ограничения) | ES2022+ (полный) |
| iOS JIT | Не требуется | Недоступен (interpreted only) |
| Бинарник | ~3 MB | ~10 MB |
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 в рантайме — все модули должны быть известны на этапе сборки.
# 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 измеряется по трём ключевым метрикам: 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 включает встроенный профилировщик памяти, доступный через Chrome DevTools. Подключитесь к приложению через Metro, откройте вкладку Memory и выберите Hermes (JavaScript) в типах снимков. Hermes поддерживает три типа снимков: Heap Snapshot (все объекты), Allocation Timeline (время жизни объектов) и Allocation Sampling (выборочный профиль). Hades GC снижает количество GC-пауз до минимума — в среднем одна пауза длительностью 2-5ms за 10 секунд работы против 10-20ms пауз у JSC за тот же период.
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 и платформы. Начиная с 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.
// 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 связаны с отказом от 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 на вашем бандле — он покажет список неподдерживаемых фич.
Часто задаваемые вопросы
В консоли приложения выполните console.log(global.HermesInternal). Если объект HermesInternal существует — приложение работает на Hermes. Альтернативно: console.log(global.HermesInternal?.getRuntimeProperties()) — выведет версию движка и параметры GC. В Release-сборках HermesInternal может быть недоступен для минимизации размера.
Проверьте настройки 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 / Fast Refresh. Во время разработки Metro запускает JavaScript-бандл без Hermes-компиляции (plain JS). Hermes-байт-код собирается только для Release-сборок. В Debug-режиме используется стандартный JavaScriptCore или Hermes в interpreted mode. Скорость Hot Reload не меняется при включённом Hermes в конфигурации — переключение происходит только на этапе production сборки.
Да, начиная с 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.
Используйте 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% меньше.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также