Hermes — е JavaScript двигател с отворен код, разработен специално за React Native и оптимизиран за мобилни устройства. За разлика от JavaScriptCore, Hermes компилира предварително JS кода в байткод на етапа на изграждане, осигурявайки бърз старт на приложението. Според Meta, Hermes Docs, 2024, Hermes се използва по подразбиране в React Native от версия 0.70.
Основни точки
Hermes — е компактен JavaScript двигател, създаден от екипа на Meta специално за React Native. Той беше обявен през 2019 г. като алтернатива на JavaScriptCore (JSC), който се използваше по подразбиране в React Native. Основната цел на Hermes е да осигури възможно най-бързо стартиране на приложения на мобилни устройства, особено на Android с ограничени ресурси.
Ключовата характеристика на Hermes е предварителната компилация (AOT — Ahead-of-Time). За разлика от традиционните JS двигатели, които компилират код по време на изпълнение (JIT — Just-in-Time), Hermes компилира JavaScript в байткод още на етапа на изграждане на приложението. Това означава, че на устройството не се извършва компилация — байткодът веднага се изпълнява от виртуалната машина на Hermes.
Hermes не е универсален JS двигател — той е оптимизиран изключително за сценарии на React Native. В него липсват възможности, които не са необходими в мобилната разработка: eval, генератори, някои ES6 функции. Това позволява двигателят да бъде по-компактен и по-бърз. Според Meta, размерът на Hermes е около 200–300 KB в компресиран вид, което е значително по-малко от JSC (около 2–3 MB).
Архитектурата на Hermes се различава от традиционните JS двигатели по липсата на JIT компилатор. Вместо това Hermes използва ефективна виртуална машина (VM), която изпълнява предварително компилиран байткод. Отказът от JIT дава три ключови предимства: предвидима производителност, по-малка консумация на памет и съкращаване на времето за стартиране.
Байткодът на Hermes е компактно представяне на JavaScript кода, оптимизирано за бързо изпълнение. На етапа на изграждане (чрез Metro) JavaScript файловете се компилират в .hbc (Hermes Bytecode) файлове. Приложението зарежда тези файлове и VM на Hermes ги изпълнява без допълнителна компилация. Процесът на изграждане е интегриран в Metro чрез плъгина hermes-transformer.
Процесът на обработка на JavaScript в Hermes се състои от три етапа: Parse — синтактичен анализ на изходния код, Compile — превод в байткод, Execute — изпълнение на байткода от виртуалната машина. Първите два етапа се изпълняват на етапа на изграждане, третият — на устройството. Това коренно се различава от JSC, където и трите етапа се извършват на устройството.
# Компилация на байткод на Hermes по време на изграждане
hermes -emit-binary -out index.hbc index.js
# Проверете размера на генерирания байткод
ls -lh index.hbc
# Показване на статистика за байткода
hermes -dump-bytecode index.hbc
# Оптимизиране на байткода за продукция
hermes -O index.js -emit-binary -O target.hbc
След компилация всички .hbc файлове се опаковат в APK или IPA заедно с родния код. При стартиране на приложението VM на Hermes зарежда байткода и започва изпълнение почти мигновено — не се изисква време за JIT загряване, типично за V8 и JSC.
Сравнението на Hermes и JavaScriptCore (JSC) помага да се разбере кога кой двигател да се избере. JSC — пълноценен JS двигател от Apple, използван в Safari. Hermes — специализиран двигател за React Native. Изборът между тях зависи от приоритетите на проекта.
| Характеристика | Hermes | JavaScriptCore |
|---|---|---|
| Компилация | AOT (на етапа на изграждане) | JIT (на устройството) |
| Време за стартиране | 50–100 ms | 200–400 ms |
| Консумация на памет | 30–40% по-малко | Базово ниво |
| Размер | ~250 KB (компресиран) | ~2 MB (компресиран) |
| Поддръжка на ES6+ | Ограничена | Пълна |
Hermes печели в скоростта на стартиране и консумацията на памет, но отстъпва на JSC в производителността при изпълнение на сложни изчисления. JIT компилацията на JSC оптимизира горещите части на кода по време на изпълнение, което дава предимство при CPU-интензивни операции. За типично React Native приложение, където актуализациите на UI и навигацията съставляват основното натоварване, Hermes осигурява по-добро потребителско изживяване благодарение на бързото стартиране.
Hermes включва няколко оптимизации, специфични за React Native. Основната от тях е интеграцията с JSI (JavaScript Interface). Hermes поддържа JSI родно, което позволява използването на новата архитектура на React Native (Fabric + Turbo Module) без допълнителни слоеве. Това прави Hermes и новата архитектура идеална двойка за максимална производителност.
Hermes използва събирач на отпадъци с поколенческа стратегия (generational GC), оптимизиран за мобилни устройства. За разлика от JSC, където събирането на отпадъци може да причини забележими паузи в UI (jank), Hermes изпълнява GC на малки порции между кадрите, минимизирайки влиянието върху потребителското изживяване. Според Meta, GC паузите в Hermes са 2–3 пъти по-кратки от тези в JSC при типични сценарии на React Native.
Hermes поддържа мързеливо зареждане на модули — JavaScript модулът се компилира само когато наистина е необходим. Това намалява размера на байткода и ускорява стартирането. Допълнително Hermes изчислява константни изрази на етапа на компилация, замествайки извиквания на функции с константни стойности там, където е възможно.
// Пример за оптимизации, специфични за Hermes
// 1. Hermes вгражда константни изрази
const TAX_RATE = 0.07;
const price = 100;
// Hermes предварително изчислява: TAX_RATE * price по време на компилация
const totalWithTax = price * (1 + TAX_RATE);
// 2. Hermes оптимизира вериги за достъп до свойства
const config = { api: { timeout: 5000 } };
// Hermes вътрешно кешира достъпа до config.api
const timeout = config.api.timeout;
fetch(url, { timeout });
Важно е да се отбележи, че Hermes поддържа дебъгване чрез Chrome DevTools (от версия Hermes 0.12). Разработчикът може да използва познати инструменти: точки на прекъсване, профилиране на памет, инспекция на променливи. Това премахва едно от основните възражения срещу Hermes в ранните версии, когато дебъгването беше ограничено.
Настройката на Hermes зависи от версията на React Native. От React Native 0.70 Hermes е включен по подразбиране за нови проекти. За проекти, създадени по-рано, или при необходимост от превключване между двигатели, настройката се извършва чрез конфигурацията на изграждане.
За Android Hermes се включва във файла android/app/build.gradle чрез флага hermesEnabled. За iOS настройката се извършва в Podfile чрез променливата :hermes_enabled. След промяна на конфигурацията е необходимо да преинсталирате pod-овете и да преизградите проекта.
// android/app/build.gradle — активиране на Hermes
project.ext.react = [
enableHermes: true
]
// iOS Podfile — активиране на Hermes
hermes_enabled = true
pod 'hermes-engine'
За да проверите дали Hermes се използва в приложението, изпълнете adb logcat | grep Hermes на Android или проверете конзолата на Xcode на iOS. При стартиране на приложението Hermes показва съобщение „Hermes VM initialized” или подобно. Можете също да изпълните globalThis.HermesInternal в JavaScript кода — ако Hermes е активен, това свойство ще бъде достъпно.
// Проверка дали Hermes работи
if (typeof globalThis.HermesInternal !== 'undefined') {
console.log('✅ Двигателят Hermes е активен');
console.log(
'Версия:',
globalThis.HermesInternal.getEngineProperties()
);
} else {
console.log('❌ Hermes не е активен (връщане към JSC)');
}
Често задавани въпроси
Да, Hermes е напълно съвместим с новата архитектура на React Native (Fabric + Turbo Module). Освен това Hermes и JSI са разработени заедно и осигуряват най-добра производителност в двойка.
Да, Hermes поддържа и двете платформи — iOS и Android. На iOS Hermes замества стандартния JavaScriptCore, осигурявайки същите предимства: бърз старт и по-малка консумация на памет.
Hermes поддържа повечето възможности на ES6+, но с ограничения: липсват eval, генератори и Proxy. Препоръчва се използване на Babel транспилация за съвместимост, както в обикновения React Native.
Hermes намалява размера на приложението благодарение на компактния байткод и по-малкия размер на самия двигател. Байткодът обикновено е с 20–30% по-компактен от съответния JS код, а самият двигател тежи ~250 KB срещу ~2 MB при JSC.
Повечето библиотеки са съвместими с Hermes. Ако библиотеката използва eval, Proxy или нестандартни възможности — проверете дали има версия, съвместима с Hermes. Можете също да използвате Babel плъгини за замяна на неподдържани конструкции.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също