Hermes — är en JavaScript-motor med AOT-kompilering (Ahead-of-Time), utvecklad av Meta för React Native och optimerad för mobila enheter med begränsat minne. Enligt den officiella bloggen Meta Engineering (2022) minskar Hermes appens starttid med 20–50% och minskar buntstorleken med 30–40% jämfört med JavaScriptCore. Till skillnad från V8 eller JSC använder Hermes inte JIT-kompilering på enheten — all JavaScript kompileras till bytekod under byggfasen via Hermes CLI. Detta är särskilt viktigt för iOS, där JIT-kompilering begränsas av App Stores policyer.
Huvudpunkter
Hermes — är en kompakt JavaScript-motor med öppen källkod (MIT-licens), skapad av Meta för React Native och optimerad för att fungera på mobila enheter med begränsade resurser. Den huvudsakliga innovationen i Hermes är att avstå från JIT-kompilering till förmån för AOT (Ahead-of-Time). Under byggfasen av React Native-appen skickar Metro Bundler den kompilerade JavaScript till Hermes CLI, som omvandlar den till HBC-bytekod (Hermes ByteCode). Denna bytekod körs direkt av motorn utan ytterligare kompilering på enheten. Detta tillvägagångssätt ger förutsägbar prestanda: ingen “uppvärmning” av JIT, inga pauser för kompilering, ingen extra batteriförbrukning. Hermes är utformat med hänsyn till mobila enheters begränsningar: lite RAM (1–4 GB), begränsad energiförbrukning och behovet av snabb kallstart. Den första offentliga utgåvan av Hermes var 2019, och från React Native 0.70 (2022) blev motorn standard på Android.
JavaScriptCore (JSC) — standard WebKit-motorn, som används av Safari och React Native före version 0.70. JSC stöder JIT-kompilering, vilket ger hög prestanda för komplexa JavaScript-operationer. JIT kräver dock uppvärmning: de första sekunderna körs koden långsammare (tolkat läge), sedan kompilerar JIT de heta delarna. På iOS är JIT praktiskt taget otillgängligt på grund av App Stores policyer (förbud mot dynamisk kodgenerering), så JSC på iOS fungerar endast i tolkat läge — prestandan sjunker. JSC har en större binär storlek (cirka 10 MB) och förbrukar mer RAM på grund av JIT-infrastrukturen. Hermes är inte beroende av JIT, vilket ger förutsägbar prestanda direkt efter start (kallstart). JSC stöder ECMAScript-standarden mer fullständigt (inklusive Proxy, BigInt, Reflect), men på bekostnad av högre resursförbrukning. För React Native-projekt där kallstart och liten storlek är kritiska — är Hermes att föredra. För projekt med tunga JS-beräkningar (spel, WebGL) — kan JSC ge högre topprestanda.
| Parameter | Hermes | JavaScriptCore |
|---|---|---|
| Kompilering | AOT (under byggfasen) | JIT + Tolkat (på enheten) |
| Kallstart | 20–50% snabbare | Grundnivå |
| Buntstorlek | 30–40% mindre | Grundnivå |
| RAM-förbrukning | 20–30% mindre | Grundnivå |
| ECMAScript | ES2020 (begränsningar) | ES2022+ (fullständig) |
| iOS JIT | Krävs inte | Inte tillgänglig (endast tolkat) |
| Binär | ~3 MB | ~10 MB |
AOT-kompilering (Ahead-of-Time) i Hermes sker i två steg. I det första steget samlar Metro Bundler JavaScript-filerna i en enda bunt och skickar den till Hermes CLI (verktyget hermesc). I det andra steget tolkar hermesc JavaScript AST, genererar mellanrepresentationen HIR (Hermes Intermediate Representation) och emitterar sedan binär HBC-bytekod. Resultatet är en fil med tillägget .hbc som endast innehåller bytekod utan original JavaScript. Hermes runtime laddar HBC direkt, utan tolkning och kompilering. Detta påskyndar starten dramatiskt: istället för att tolka tusentals JS-rader (async) läser motorn ett förkompilerat binärt format. AOT minskar också storleken: bytekod är i genomsnitt 30% mer kompakt än JavaScript AST. Nackdelen med AOT — omöjligheten att köra eval, new Function eller dynamisk require under körtid — alla moduler måste vara kända under byggfasen.
# Installera Hermes CLI fristående
npm install hermes-engine
# Kompilera JS till HBC-bytekod
npx hermesc -emit-binary -out bundle.hbc bundle.js
# Bytekodsstatistik
npx hermesc -dump-bytecode bundle.hbc # shows HBC instructions
# Original JS vs HBC-storlek
wc -c bundle.js # 2,300,000 bytes
wc -c bundle.hbc # 1,450,000 bytes (37% reduction)
Prestandan för Hermes mäts med tre nyckeltal: Time-To-Interactive (TTI), APK/IPA-storlek och RAM-förbrukning. Enligt Meta minskar Hermes på Android TTI med 34% jämfört med JSC: från 4,2 sekunder till 2,8 sekunder på en mellanklass enhet (Moto G7). APK-storleken minskar med 28% tack vare kompakt bytekod och frånvaro av JIT-bibliotek. RAM-förbrukningen är i genomsnitt 22% lägre vid samma belastning — detta är särskilt viktigt för enheter med 2–3 GB RAM. På iOS är fördelen ännu större: eftersom JSC inte kan använda JIT ger Hermes en TTI-förbättring på upp till 45%. Mätvärdena baseras på Metas tester med appen Facebook Lite. I verkliga projekt varierar fördelen: för enkla skärmar (listor, text) ger Hermes större förbättring, för tunga animationer — mindre. Profileringsverktyg: React Native Profiler + hermes profile --heap.
Hermes innehåller en inbyggd minnesprofilerare, tillgänglig via Chrome DevTools. Anslut till appen via Metro, öppna fliken Memory och välj Hermes (JavaScript) i snapshot-typerna. Hermes stöder tre typer av snapshots: Heap Snapshot (alla objekt), Allocation Timeline (objektens livslängd) och Allocation Sampling (selektiv profil). Hades GC minskar antalet GC-pauser till ett minimum — i genomsnitt en paus på 2–5 ms per 10 sekunders arbete jämfört med pauser på 10–20 ms hos JSC under samma period.
Hades GC — är sopröjaren i Hermes, utformad för mobila scenarier med minimala pauser. Till skillnad från mark-sweep GC i JSC använder Hades samtidig (concurrent) insamling: samlaren arbetar parallellt med den huvudsakliga exekveringstråden och stoppar den endast under korta perioder. Hades GC delar upp högen i generationer: den unga generationen (nursery) samlas ofta och snabbt (Scavenge), den gamla generationen samlas mer sällan och med mindre pauser. Högstorleken är konfigurerbar: som standard — 2/3 av appens tillgängliga RAM, minimitröskel — 32 MB. Hades använder inte stop-the-world-metoden: även fullständig insamling av den gamla generationen tar inte mer än 5–8 ms. Samlaren är optimerad för det typiska mobila scenariot: många kortlivade objekt (tillfälliga strängar, React fibre-objekt), få långlivade. För appar med intensiv objektskapande (listor, animationer) ger Hades jämnare FPS jämfört med JSC.
Aktivering av Hermes beror på React Native-versionen och plattformen. Från och med React Native 0.70 är Hermes som standard aktiverat för Android i nya projekt. För iOS är Hermes valfritt. För att aktivera på Android: i filen android/app/build.gradle ställ in enableHermes: true i blocket project.ext.react.enableHermes. För iOS: ställ in hermes_enabled till true i Podfile via use_react_native!(:path => config[:reactNativePath], :hermes_enabled => true). Efter aktivering kör du pod install. För befintliga projekt, kontrollera bibliotekens kompatibilitet: Hermes stöder inte Proxy, eval och vissa ES2021-funktioner. Använd npx react-native info för att kontrollera konfigurationen. För att växla mellan Hermes och JSC, ändra flaggan och utför clean rebuild.
// android/app/build.gradle — aktivera Hermes
project.ext.react = [
enableHermes: true,
cliPath: "node_modules/react-native/cli.js"
]
// iOS/Podfile — aktivera Hermes på 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
De huvudsakliga begränsningarna för Hermes är relaterade till att avstå från JIT. Hermes stöder inte: Proxy och Reflect API (används i MobX, Vue, vissa tillståndshanterare), BigInt (stora tal), Symbol.toStringTag, WeakRef och FinalizationRegistry. Funktionerna eval och new Function genererar ett undantag under körning. Återanrop av metoderna Array.prototype.flat och flatMap med argumentet this fungerar med begränsningar. Datumformat ISO 8601 med tidszoner bearbetas inte fullständigt. De flesta av dessa begränsningar påverkar inte typiska React Native-appar: React och React Native använder en begränsad uppsättning ES-funktioner. Om ett bibliotek kräver Proxy (t.ex. MobX 6+ med Proxy), använd configure({ useProxies: false }) eller välj ett alternativ. För att kontrollera kompatibiliteten för befintlig kod, kör npx hermesc -check på din bunt — den visar en lista över funktioner som inte stöds.
Vanliga frågor
I appens konsol, kör console.log(global.HermesInternal). Om objektet HermesInternal finns — körs appen på Hermes. Alternativt: console.log(global.HermesInternal?.getRuntimeProperties()) — visar motorversionen och GC-parametrar. I Release-versioner kan HermesInternal vara otillgängligt för att minimera storleken.
Kontrollera Podfile-inställningarna: Hermes på iOS kräver New Architecture (Fabric Renderer). Ställ in :hermes_enabled => true, kör pod install --repo-update. Om projektet uppdateras från React Native under 0.70, kontrollera bibliotekens kompatibilitet med New Architecture. Inaktivera Hermes om ett tredjepartsbibliotek kräver JSC — för detta ändrar du flaggan till false och installerar om Pods.
Nej, Hermes påverkar inte Hot Reload / Fast Refresh. Under utveckling kör Metro JavaScript-bunten utan Hermes-kompilering (plain JS). Hermes-bytecode skapas endast för Release-versioner. I Debug-läge används standard JavaScriptCore eller Hermes i tolkat läge. Hot Reload-hastigheten ändras inte när Hermes är aktiverat i konfigurationen — växling sker endast under produktionsbyggfasen.
Ja, från och med Expo SDK 45 stöds Hermes för managed workflow. I app.json ställ in "jsEngine": "hermes". För bare workflow fungerar Hermes som i ett vanligt React Native-projekt. Expo Go stöder inte Hermes — använd Expo Dev Client eller EAS Build för versioner med Hermes. Kontrollera bibliotekens kompatibilitet genom expo doctor.
Använd React Native Performance Monitor (FPS-mätvärden) och Hermes Profiling Tools. Bygg två versioner av appen — med Hermes och JSC — på samma enhet. Mät: kallstart (från klick på ikon till första interaktiva skärm), TTI (Time-To-Interactive), APK/IPA-storlek och maximal RAM-förbrukning. Kör testerna minst 3 gånger för varje konfiguration. Typisk fördel för Hermes: start 20–40% snabbare, RAM 15–25% mindre.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också