Hermes ist eine JavaScript-Engine mit AOT-Kompilierung (Ahead-of-Time), die von Meta für React Native entwickelt und für mobile Geräte mit begrenztem Arbeitsspeicher optimiert wurde. Laut dem offiziellen Meta Engineering Blog (2022) reduziert Hermes die App-Startzeit um 20-50 % und verringert die Bundle-Größe um 30-40 % im Vergleich zu JavaScriptCore. Im Gegensatz zu V8 oder JSC verwendet Hermes keine JIT-Kompilierung auf dem Gerät — das gesamte JavaScript wird während der Build-Phase über die Hermes CLI in Bytecode kompiliert. Dies ist besonders wichtig für iOS, wo die JIT-Kompilierung durch die App Store-Richtlinien eingeschränkt ist.
Wichtige Punkte
Hermes ist eine kompakte Open-Source-JavaScript-Engine (MIT-Lizenz), die von Meta für React Native entwickelt und für den Betrieb auf ressourcenbeschränkten mobilen Geräten optimiert wurde. Die wichtigste Innovation von Hermes ist der Verzicht auf JIT-Kompilierung zugunsten von AOT (Ahead-of-Time). Während der Build-Phase der React Native-App übergibt der Metro Bundler das kompilierte JavaScript an die Hermes CLI, die es in HBC-Bytecode (Hermes ByteCode) umwandelt. Dieser Bytecode wird direkt von der Engine ohne zusätzliche Kompilierung auf dem Gerät ausgeführt. Dieser Ansatz bietet eine vorhersagbare Leistung: kein JIT-Aufwärmen, keine Kompilierungspausen, kein zusätzlicher Batterieverbrauch. Hermes wurde unter Berücksichtigung der Einschränkungen mobiler Geräte entwickelt: wenig RAM (1-4 GB), begrenzter Stromverbrauch und die Notwendigkeit eines schnellen Kaltstarts. Die erste öffentliche Version von Hermes wurde 2019 veröffentlicht, und ab React Native 0.70 (2022) wurde die Engine zum Standard auf Android.
JavaScriptCore (JSC) ist die standardmäßige WebKit-Engine, die von Safari und React Native vor Version 0.70 verwendet wird. JSC unterstützt JIT-Kompilierung, was eine hohe Leistung für komplexe JavaScript-Operationen bietet. Allerdings benötigt JIT eine Aufwärmphase: Die ersten Sekunden der Ausführung sind langsamer (interpretierter Modus), dann kompiliert JIT die heißen Pfade. Auf iOS ist JIT aufgrund der App Store-Richtlinien (Verbot dynamischer Codegenerierung) praktisch nicht verfügbar, daher arbeitet JSC auf iOS nur im interpretierten Modus — die Leistung sinkt. JSC hat eine größere Binärgröße (etwa 10 MB) und verbraucht aufgrund der JIT-Infrastruktur mehr RAM. Hermes ist nicht von JIT abhängig und bietet direkt nach dem Start (Kaltstart) eine vorhersagbare Leistung. JSC unterstützt den ECMAScript-Standard umfassender (einschließlich Proxy, BigInt, Reflect), allerdings auf Kosten eines höheren Ressourcenverbrauchs. Für React Native-Projekte, bei denen Kaltstart und kleine Größe entscheidend sind, ist Hermes vorzuziehen. Für Projekte mit schweren JS-Berechnungen (Spiele, WebGL) kann JSC eine höhere Spitzenleistung bieten.
| Parameter | Hermes | JavaScriptCore |
|---|---|---|
| Kompilierung | AOT (beim Build) | JIT + Interpretiert (auf dem Gerät) |
| Kaltstart | 20-50 % schneller | Basisniveau |
| Bundle-Größe | 30-40 % kleiner | Basisniveau |
| RAM-Verbrauch | 20-30 % weniger | Basisniveau |
| ECMAScript | ES2020 (Einschränkungen) | ES2022+ (vollständig) |
| iOS JIT | Nicht erforderlich | Nicht verfügbar (nur interpretiert) |
| Binär | ~3 MB | ~10 MB |
Die AOT-Kompilierung (Ahead-of-Time) in Hermes erfolgt in zwei Phasen. In der ersten Phase sammelt der Metro Bundler die JavaScript-Dateien in einem einzigen Bundle und übergibt sie an die Hermes CLI (das Dienstprogramm hermesc). In der zweiten Phase parst hermesc den JavaScript-AST, generiert eine Zwischendarstellung HIR (Hermes Intermediate Representation) und gibt dann binären HBC-Bytecode aus. Das Ergebnis ist eine .hbc-Datei, die nur Bytecode ohne das ursprüngliche JavaScript enthält. Die Hermes-Laufzeitumgebung lädt HBC direkt, ohne Parsen und Kompilieren. Dies beschleunigt den Start radikal: Statt Tausende von JS-Zeilen zu parsen (async), liest die Engine ein vorcompiliertes Binärformat. AOT reduziert auch die Größe: Bytecode ist im Durchschnitt 30 % kompakter als der JavaScript-AST. Der Nachteil von AOT ist die Unfähigkeit, eval, new Function oder dynamisches require zur Laufzeit auszuführen — alle Module müssen zum Zeitpunkt des Builds bekannt sein.
# Hermes CLI standalone installieren
npm install hermes-engine
# JS in HBC-Bytecode kompilieren
npx hermesc -emit-binary -out bundle.hbc bundle.js
# Bytecode-Statistiken
npx hermesc -dump-bytecode bundle.hbc # shows HBC instructions
# Original JS vs HBC-Größe
wc -c bundle.js # 2,300,000 bytes
wc -c bundle.hbc # 1,450,000 bytes (37% reduction)
Die Leistung von Hermes wird anhand von drei Hauptkennzahlen gemessen: Time-To-Interactive (TTI), APK/IPA-Größe und RAM-Verbrauch. Laut Meta-Daten reduziert Hermes auf Android die TTI um 34 % im Vergleich zu JSC: von 4,2 Sekunden auf 2,8 Sekunden auf einem Mittelklassegerät (Moto G7). Die APK-Größe verringert sich dank des kompakten Bytecodes und des Fehlens von JIT-Bibliotheken um 28 %. Der RAM-Verbrauch ist bei gleicher Last durchschnittlich 22 % niedriger — dies ist besonders wichtig für Geräte mit 2-3 GB RAM. Auf iOS ist der Gewinn noch signifikanter: Da JSC kein JIT verwenden kann, verbessert Hermes die TTI um bis zu 45 %. Die Kennzahlen basieren auf Tests von Meta mit der Facebook Lite-App. In realen Projekten variiert der Gewinn: Bei einfachen Bildschirmen (Listen, Text) bringt Hermes eine größere Verbesserung, bei schweren Animationen eine geringere. Profilierungswerkzeug: React Native Profiler + hermes profile --heap.
Hermes enthält einen integrierten Speicherprofilierer, der über Chrome DevTools zugänglich ist. Verbinden Sie sich über Metro mit der App, öffnen Sie den Tab Memory und wählen Sie Hermes (JavaScript) aus den Snapshot-Typen. Hermes unterstützt drei Snapshot-Typen: Heap Snapshot (alle Objekte), Allocation Timeline (Lebensdauer von Objekten) und Allocation Sampling (Stichprobenprofil). Hades GC reduziert GC-Pausen auf ein Minimum — durchschnittlich eine 2-5ms Pause pro 10 Sekunden Betrieb, verglichen mit 10-20ms Pausen bei JSC im gleichen Zeitraum.
Hades GC ist der Garbage Collector in Hermes, der für mobile Szenarien mit minimalen Pausen entwickelt wurde. Im Gegensatz zum mark-sweep GC in JSC verwendet Hades die konkurrente (concurrent) Sammlung: Der Collector arbeitet parallel zum Hauptausführungsthread und stoppt ihn nur für kurze Intervalle. Hades GC unterteilt den Heap in Generationen: Die junge Generation (nursery) wird häufig und schnell gesammelt (Scavenge), die alte Generation wird seltener und mit kürzeren Pausen gesammelt. Die Heap-Größe ist konfigurierbar: standardmäßig 2/3 des verfügbaren App-RAM, Mindestschwelle 32 MB. Hades verwendet keinen Stop-the-World-Ansatz: Selbst eine vollständige Sammlung der alten Generation dauert nicht länger als 5-8ms. Der Collector ist für typische mobile Szenarien optimiert: viele kurzlebige Objekte (temporäre Strings, React-Fiber-Objekte), wenige langlebige. Für Anwendungen mit intensiver Objekterstellung (Listen, Animationen) bietet Hades eine flüssigere FPS im Vergleich zu JSC.
Die Aktivierung von Hermes hängt von der React Native-Version und der Plattform ab. Ab React Native 0.70 ist Hermes für Android in neuen Projekten standardmäßig aktiviert. Für iOS ist Hermes optional. Zur Aktivierung auf Android: Setzen Sie in der Datei android/app/build.gradle im Block project.ext.react.enableHermes enableHermes: true. Für iOS: Setzen Sie hermes_enabled im Podfile über use_react_native!(:path => config[:reactNativePath], :hermes_enabled => true) auf true. Führen Sie nach der Aktivierung pod install aus. Überprüfen Sie bei vorhandenen Projekten die Bibliothekskompatibilität: Hermes unterstützt Proxy, eval und einige ES2021-Funktionen nicht. Verwenden Sie npx react-native info zur Überprüfung der Konfiguration. Zum Wechseln zwischen Hermes und JSC ändern Sie das Flag und führen Sie einen sauberen Neubuild durch.
// android/app/build.gradle — Hermes aktivieren
project.ext.react = [
enableHermes: true,
cliPath: "node_modules/react-native/cli.js"
]
// iOS/Podfile — Hermes auf iOS aktivieren
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
Die Haupteinschränkungen von Hermes hängen mit dem Fehlen von JIT zusammen. Hermes unterstützt nicht: Proxy und Reflect API (verwendet in MobX, Vue, einigen State-Managern), BigInt (große Zahlen), Symbol.toStringTag, WeakRef und FinalizationRegistry. Die Funktionen eval und new Function werfen zur Laufzeit eine Ausnahme. Callbacks der Methoden Array.prototype.flat und flatMap mit einem this-Argument arbeiten mit Einschränkungen. ISO 8601-Datumsformate mit Zeitzonen werden nicht vollständig verarbeitet. Die meisten dieser Einschränkungen betreffen typische React Native-Anwendungen nicht: React und React Native verwenden einen begrenzten Satz von ES-Funktionen. Wenn eine Bibliothek Proxy benötigt (z. B. MobX 6+ mit Proxy), verwenden Sie configure({ useProxies: false }) oder wählen Sie eine Alternative. Um die Kompatibilität vorhandenen Codes zu überprüfen, führen Sie npx hermesc -check auf Ihrem Bundle aus — es zeigt die Liste der nicht unterstützten Funktionen an.
Häufig gestellte Fragen
Führen Sie in der App-Konsole console.log(global.HermesInternal) aus. Wenn das HermesInternal-Objekt existiert — läuft die App auf Hermes. Alternativ: console.log(global.HermesInternal?.getRuntimeProperties()) — zeigt die Engine-Version und GC-Parameter an. In Release-Builds kann HermesInternal zur Größenminimierung nicht verfügbar sein.
Überprüfen Sie Ihre Podfile-Einstellungen: Hermes auf iOS benötigt New Architecture (Fabric Renderer). Setzen Sie :hermes_enabled => true, führen Sie pod install --repo-update aus. Wenn das Projekt von React Native unter 0.70 aktualisiert wird, überprüfen Sie die Bibliothekskompatibilität mit New Architecture. Deaktivieren Sie Hermes, wenn eine Drittanbieter-Bibliothek JSC benötigt — setzen Sie das Flag auf false und installieren Sie die Pods neu.
Nein, Hermes beeinflusst den Hot Reload / Fast Refresh nicht. Während der Entwicklung führt Metro das JavaScript-Bundle ohne Hermes-Kompilierung (reines JS) aus. Hermes-Bytecode wird nur für Release-Builds kompiliert. Im Debug-Modus wird standardmäßig JavaScriptCore oder Hermes im interpretierten Modus verwendet. Die Geschwindigkeit des Hot Reload ändert sich nicht, wenn Hermes in der Konfiguration aktiviert ist — das Umschalten erfolgt nur in der Produktions-Build-Phase.
Ja, ab Expo SDK 45 wird Hermes für den managed Workflow unterstützt. Geben Sie in app.json "jsEngine": "hermes" an. Für den bare Workflow funktioniert Hermes wie in einem normalen React Native-Projekt. Expo Go unterstützt Hermes nicht — verwenden Sie Expo Dev Client oder EAS Build für Builds mit Hermes. Überprüfen Sie die Bibliothekskompatibilität mit expo doctor.
Verwenden Sie den React Native Performance Monitor (FPS-Metriken) und die Hermes Profiling Tools. Erstellen Sie zwei Versionen der App — mit Hermes und JSC — auf demselben Gerät. Messen Sie: Kaltstart (vom Tippen auf das Symbol bis zum ersten interaktiven Bildschirm), TTI (Time-To-Interactive), APK/IPA-Größe und maximalen RAM-Verbrauch. Führen Sie die Tests mindestens 3 Mal für jede Konfiguration durch. Typischer Hermes-Vorteil: 20-40 % schnellerer Start, 15-25 % weniger RAM.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch