Hermes è un motore JavaScript open source sviluppato appositamente per React Native e ottimizzato per dispositivi mobili. A differenza di JavaScriptCore, Hermes precompila il codice JS in bytecode durante la fase di build, garantendo un avvio rapido dell'applicazione. Secondo Meta, Hermes Docs, 2024, Hermes viene utilizzato per impostazione predefinita in React Native a partire dalla versione 0.70.
Punti chiave
Hermes è un motore JavaScript compatto creato dal team di Meta appositamente per React Native. È stato annunciato nel 2019 come alternativa a JavaScriptCore (JSC), che veniva utilizzato per impostazione predefinita in React Native. L'obiettivo principale di Hermes è fornire l'avvio più veloce possibile per le applicazioni mobili, specialmente su Android con risorse limitate.
La caratteristica principale di Hermes è la compilazione anticipata (AOT — Ahead-of-Time). A differenza dei motori JS tradizionali che compilano il codice in fase di esecuzione (JIT — Just-in-Time), Hermes compila JavaScript in bytecode durante la fase di build dell'app. Ciò significa che nessuna compilazione avviene sul dispositivo — il bytecode viene immediatamente eseguito dalla macchina virtuale Hermes.
Hermes non è un motore JS universale — è ottimizzato esclusivamente per scenari React Native. Non dispone di funzionalità non necessarie nello sviluppo mobile: eval, generatori e alcune funzionalità ES6. Ciò consente al motore di essere più compatto e veloce. Secondo Meta, la dimensione di Hermes è di circa 200–300 KB compresso, significativamente inferiore a JSC (circa 2–3 MB).
L'architettura di Hermes si differenzia dai motori JS tradizionali per l'assenza di un compilatore JIT. Invece, Hermes utilizza una macchina virtuale (VM) efficiente che esegue bytecode precompilato. Abbandonare JIT offre tre vantaggi principali: prestazioni prevedibili, minor consumo di memoria e riduzione del tempo di avvio.
Il bytecode di Hermes è una rappresentazione compatta del codice JavaScript ottimizzata per l'esecuzione veloce. Durante la fase di build (tramite Metro), i file JavaScript vengono compilati in file .hbc (Hermes Bytecode). L'app carica questi file e la VM Hermes li esegue senza compilazione aggiuntiva. Il processo di build è integrato in Metro tramite il plugin hermes-transformer.
Il flusso di elaborazione JavaScript in Hermes consiste in tre fasi: Parse — analisi sintattica del codice sorgente, Compile — traduzione in bytecode, Execute — esecuzione del bytecode da parte della macchina virtuale. Le prime due fasi vengono eseguite durante la fase di build, la terza sul dispositivo. Questo è fondamentalmente diverso da JSC, dove tutte e tre le fasi vengono eseguite sul dispositivo.
# Compilazione del bytecode Hermes durante la build
hermes -emit-binary -out index.hbc index.js
# Verificare la dimensione del bytecode generato
ls -lh index.hbc
# Mostra statistiche bytecode
hermes -dump-bytecode index.hbc
# Ottimizzare il bytecode per la produzione
hermes -O index.js -emit-binary -O target.hbc
Dopo la compilazione, tutti i file .hbc vengono impacchettati in APK o IPA insieme al codice nativo. Quando l'app si avvia, la VM Hermes carica il bytecode e inizia l'esecuzione quasi istantaneamente — non è necessario il tempo di riscaldamento JIT, tipico di V8 e JSC.
Confrontare Hermes e JavaScriptCore (JSC) aiuta a capire quando scegliere quale motore. JSC è un motore JS completo di Apple, utilizzato in Safari. Hermes è un motore specializzato per React Native. La scelta tra loro dipende dalle priorità del progetto.
| Caratteristica | Hermes | JavaScriptCore |
|---|---|---|
| Compilazione | AOT (durante la build) | JIT (sul dispositivo) |
| Tempo di avvio | 50–100 ms | 200–400 ms |
| Consumo di memoria | 30–40% in meno | Livello base |
| Dimensione | ~250 KB (compresso) | ~2 MB (compresso) |
| Supporto ES6+ | Limitato | Completo |
Hermes vince in velocità di avvio e consumo di memoria, ma è inferiore a JSC nelle prestazioni di calcolo complesse. La compilazione JIT di JSC ottimizza i percorsi di codice caldo durante l'esecuzione, dandogli un vantaggio nelle operazioni intensive di CPU. Per un'app React Native tipica, dove gli aggiornamenti dell'interfaccia utente e la navigazione costituiscono il carico di lavoro principale, Hermes offre un'esperienza utente migliore grazie all'avvio rapido.
Hermes include diverse ottimizzazioni specifiche per React Native. La principale è l'integrazione con JSI (JavaScript Interface). Hermes supporta JSI nativamente, consentendo l'uso della nuova architettura React Native (Fabric + Turbo Modules) senza livelli aggiuntivi. Ciò rende Hermes e la nuova architettura la coppia ideale per le massime prestazioni.
Hermes utilizza un garbage collector generazionale (generational GC) ottimizzato per dispositivi mobili. A differenza di JSC, dove la garbage collection può causare pause evidenti nell'interfaccia utente (jank), Hermes esegue GC in piccole porzioni tra i frame, minimizzando l'impatto sull'esperienza utente. Secondo Meta, le pause GC in Hermes sono 2–3 volte più brevi rispetto a JSC in scenari React Native tipici.
Hermes supporta il caricamento lazy dei moduli — un modulo JavaScript viene compilato solo quando effettivamente necessario. Ciò riduce la dimensione del bytecode e accelera l'avvio. Inoltre, Hermes valuta le espressioni costanti al momento della compilazione, sostituendo le chiamate di funzione con valori costanti dove possibile.
// Esempio di ottimizzazioni specifiche di Hermes
// 1. Hermes inlinea le espressioni costanti
const TAX_RATE = 0.07;
const price = 100;
// Hermes pre-calcola: TAX_RATE * price durante la compilazione
const totalWithTax = price * (1 + TAX_RATE);
// 2. Hermes ottimizza le catene di accesso alle proprietà
const config = { api: { timeout: 5000 } };
// Hermes memorizza nella cache l'accesso a config.api internamente
const timeout = config.api.timeout;
fetch(url, { timeout });
È importante notare che Hermes supporta il debug tramite Chrome DevTools (a partire da Hermes 0.12). Gli sviluppatori possono utilizzare strumenti familiari: punti di interruzione, profilazione della memoria, ispezione delle variabili. Ciò elimina una delle principali obiezioni a Hermes nelle versioni iniziali, dove il debug era limitato.
La configurazione di Hermes dipende dalla versione di React Native. A partire da React Native 0.70, Hermes è abilitato per impostazione predefinita per i nuovi progetti. Per i progetti creati in precedenza, o quando si cambia motore, la configurazione viene effettuata tramite le impostazioni di build.
Per Android, Hermes viene abilitato nel file android/app/build.gradle tramite il flag hermesEnabled. Per iOS, la configurazione viene effettuata nel Podfile tramite la variabile :hermes_enabled. Dopo aver modificato la configurazione, è necessario reinstallare i pod e ricostruire il progetto.
// android/app/build.gradle — abilitare Hermes
project.ext.react = [
enableHermes: true
]
// iOS Podfile — abilitare Hermes
hermes_enabled = true
pod 'hermes-engine'
Per verificare che Hermes sia in esecuzione nella tua app, esegui adb logcat | grep Hermes su Android o controlla la console di Xcode su iOS. All'avvio dell'app, Hermes restituisce un messaggio come “Hermes VM initialized” o simile. Puoi anche verificare globalThis.HermesInternal nel codice JavaScript — se Hermes è attivo, questa proprietà sarà disponibile.
// Verificare se Hermes è in esecuzione
if (typeof globalThis.HermesInternal !== 'undefined') {
console.log('✅ Motore Hermes attivo');
console.log(
'Versione:',
globalThis.HermesInternal.getEngineProperties()
);
} else {
console.log('❌ Hermes non attivo (fallback a JSC)');
}
Domande frequenti
Sì, Hermes è completamente compatibile con la nuova architettura React Native (Fabric + Turbo Modules). Inoltre, Hermes e JSI sono stati sviluppati insieme e offrono le migliori prestazioni in coppia.
Sì, Hermes supporta entrambe le piattaforme — iOS e Android. Su iOS, Hermes sostituisce JavaScriptCore standard, offrendo gli stessi vantaggi: avvio rapido e minor consumo di memoria.
Hermes supporta la maggior parte delle funzionalità ES6+, ma con limitazioni: eval, generatori e Proxy non sono disponibili. Si consiglia di utilizzare la transpilazione Babel per la compatibilità, come in React Native standard.
Hermes riduce la dimensione dell'app grazie al bytecode compatto e alla minore dimensione del motore. Il bytecode è tipicamente il 20–30% più compatto del codice JS equivalente, e il motore stesso pesa ~250 KB contro ~2 MB di JSC.
La maggior parte delle librerie è compatibile con Hermes. Se una libreria utilizza eval, Proxy o funzionalità non standard — controlla se esiste una versione compatibile con Hermes. Puoi anche utilizzare plugin Babel per sostituire costrutti non supportati.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche