Hermes — vad är det, JS-motor för React Native och funktionsprincip

Författare: IT Sectr Publicerad: 2026-07-06 Lästid: 9 min

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 — JavaScript-motor med AOT-kompilering, utvecklad av Meta för React Native
  • AOT vs JIT — Hermes kompilerar JS till bytekod under byggfasen, utan JIT på enheten
  • Prestanda — app-start 20–50% snabbare, bunt 30–40% mindre
  • Hades GC — sopröjare med låg latens, optimerad för mobila scenarier
  • Standard — ECMAScript 2020+ utan Proxy, BigInt och Reflect i full omfattning

Vad är Hermes

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.

Hermes vs JavaScriptCore: jämförelse av motorer

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.

ParameterHermesJavaScriptCore
KompileringAOT (under byggfasen)JIT + Tolkat (på enheten)
Kallstart20–50% snabbareGrundnivå
Buntstorlek30–40% mindreGrundnivå
RAM-förbrukning20–30% mindreGrundnivå
ECMAScriptES2020 (begränsningar)ES2022+ (fullständig)
iOS JITKrävs inteInte tillgänglig (endast tolkat)
Binär~3 MB~10 MB

AOT-kompilering: hur förbyggande fungerar

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.

bash
# 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)

Prestandamätvärden för Hermes

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.

Minnesprofilering med Hermes

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.

Sopröjaren Hades GC

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.

Så här aktiverar du Hermes i ett React Native-projekt

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.

groovy
// 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

Begränsningar för Hermes: vad som inte stöds

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.

  • Proxy / Reflect — inte implementerade; bibliotek med Proxy kräver fallback-läge
  • BigInt — inte tillgängligt; använd bignumber.js-bibliotek för stora tal
  • eval / new Function — anrop throw; alla moduler måste vara statiska
  • WeakRef / FinalizationRegistry — stöds inte; inget alternativ finns
  • Symbol.toStringTag — ignoreras; instanceof fungerar korrekt

Vanliga frågor

Hur kontrollerar jag om appen körs på Hermes?

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.

Varför kraschar appen på iOS efter att Hermes aktiverats?

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.

Påverkar Hermes Hot Reload under utveckling?

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.

Kan Hermes användas med Expo?

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.

Hur jämför jag prestandan för Hermes och JSC i mitt projekt?

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

  • Hermes — Metas JavaScript-motor med AOT-kompilering för React Native, standard på Android från 0.70
  • AOT-kompilering ger förutsägbar prestanda utan JIT-uppvärmning på enheten
  • Kallstart 20–50% snabbare, buntstorlek 30–40% mindre vs JavaScriptCore
  • Hades GC — samtidig sopröjare med pauser på 2–5 ms istället för 10–20 ms hos JSC
  • Begränsningar: Proxy, BigInt, eval, WeakRef stöds inte — kontrollera bibliotek
  • Aktivering: enableHermes i build.gradle (Android) eller hermes_enabled i Podfile (iOS)
  • Hermes CLI möjliggör kompilering av .hbc-bytekod och minnesprofilering via DevTools
  • Hermes påverkar inte Hot Reload under utveckling — bytekod skapas endast för Release

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.

Diskutera projektet

Läs också