Hermesは、React Native専用に開発され、モバイルデバイス向けに最適化されたオープンソースのJavaScriptエンジンです。JavaScriptCoreとは異なり、HermesはビルドフェーズでJSコードを事前にバイトコードにコンパイルし、アプリケーションの高速起動を実現します。Meta、Hermes Docs、2024によると、HermesはReact Nativeバージョン0.70からデフォルトで使用されています。
主なポイント
Hermesは、MetaチームがReact Native専用に作成したコンパクトなJavaScriptエンジンです。2019年に、React Nativeでデフォルトで使用されていたJavaScriptCore(JSC)の代替として発表されました。Hermesの主な目標は、モバイルアプリケーション、特にリソースが限られたAndroidでの最も高速な起動を提供することです。
Hermesの主要な機能は事前コンパイル(AOT — Ahead-of-Time)です。実行時にコードをコンパイルする伝統的なJSエンジン(JIT — Just-in-Time)とは異なり、HermesはアプリのビルドフェーズでJavaScriptをバイトコードにコンパイルします。つまり、デバイス上ではコンパイルは行われず、バイトコードはHermes仮想マシンによって即座に実行されます。
Hermesは汎用JSエンジンではなく、React Nativeのシナリオ専用に最適化されています。モバイル開発で不要な機能(eval、ジェネレーター、一部のES6機能)は省かれています。これにより、エンジンはよりコンパクトで高速になっています。Metaによると、Hermesのサイズは圧縮状態で約200–300KBであり、JSC(約2–3MB)よりも大幅に小さいです。
Hermesのアーキテクチャは、JITコンパイラがない点で伝統的なJSエンジンとは異なります。代わりに、Hermesは事前コンパイルされたバイトコードを実行する効率的な仮想マシン(VM)を使用します。JITを廃止することで、予測可能なパフォーマンス、低メモリ消費、起動時間の短縮という3つの主な利点が得られます。
Hermesのバイトコードは、高速実行向けに最適化されたJavaScriptコードのコンパクトな表現です。ビルドフェーズ(Metro経由)で、JavaScriptファイルは.hbc(Hermes Bytecode)ファイルにコンパイルされます。アプリはこれらのファイルをロードし、Hermes VMが追加のコンパイルなしで実行します。ビルドプロセスはhermes-transformerプラグインを通じてMetroに統合されています。
HermesでのJavaScript処理フローは3つの段階で構成されています:Parse — ソースコードの構文解析、Compile — バイトコードへの変換、Execute — 仮想マシンによるバイトコードの実行。最初の2つの段階はビルドフェーズで実行され、3番目はデバイス上で実行されます。これは、3つの段階すべてがデバイス上で実行される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にパッケージ化されます。アプリが起動すると、Hermes VMはバイトコードをロードし、ほぼ即座に実行を開始します— V8やJSCに典型的なJITウォームアップ時間は必要ありません。
HermesとJavaScriptCore(JSC)の比較は、いつどちらのエンジンを選ぶべきかを理解するのに役立ちます。JSCはApple製の機能を備えたJSエンジンで、Safariで使用されています。HermesはReact Native向けの専門エンジンです。どちらを選ぶかは、プロジェクトの優先事項によって異なります。
| 特性 | Hermes | JavaScriptCore |
|---|---|---|
| コンパイル | AOT(ビルド時) | JIT(デバイス上) |
| 起動時間 | 50–100ミリ秒 | 200–400ミリ秒 |
| メモリ使用量 | 30–40%少ない | ベースライン |
| サイズ | ~250KB(圧縮) | ~2MB(圧縮) |
| ES6+サポート | 制限あり | 完全 |
Hermesは起動速度とメモリ消費で勝りますが、複雑な計算パフォーマンスではJSCに及びません。JSCのJITコンパイルは実行中にホットコードパスを最適化し、CPU負荷の高い操作で利点をもたらします。UI更新とナビゲーションが主なワークロードを構成する典型的なReact Nativeアプリでは、Hermesは高速起動により優れたユーザーエクスペリエンスを提供します。
Hermesには、React Native固有のいくつかの最適化が含まれています。主なものはJSI(JavaScript Interface)との統合です。HermesはJSIをネイティブでサポートしており、追加レイヤーなしで新しいReact Nativeアーキテクチャ(Fabric + Turbo Modules)を使用できます。これにより、Hermesと新しいアーキテクチャは最大のパフォーマンスを発揮する理想的なペアになります。
Hermesはモバイルデバイス向けに最適化された世代別ガーベジコレクタ(generational GC)を使用します。ガーベジコレクションがUIの顕著な停止(ジャンク)を引き起こす可能性があるJSCとは異なり、Hermesはフレーム間でGCを少量ずつ実行し、ユーザーエクスペリエンスへの影響を最小限に抑えます。Metaによると、典型的なReact NativeシナリオでのHermesのGC停止時間はJSCの2–3分の1です。
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に対する主な反対論の1つが解消されます。
Hermesの設定はReact Nativeのバージョンによって異なります。React Native 0.70以降、Hermesは新規プロジェクトでデフォルトで有効になっています。以前に作成されたプロジェクト、またはエンジンを切り替える場合は、ビルド設定を通じて構成します。
Androidの場合、Hermesはandroid/app/build.gradleファイルでhermesEnabledフラグを使用して有効にします。iOSの場合、Podfileで:hermes_enabled変数を使用して構成します。構成を変更した後は、ポッドを再インストールし、プロジェクトを再ビルドする必要があります。
// android/app/build.gradle — Hermesを有効化
project.ext.react = [
enableHermes: true
]
// iOS Podfile — Hermesを有効化
hermes_enabled = true
pod 'hermes-engine'
アプリでHermesが実行されていることを確認するには、Androidでadb logcat | grep Hermesを実行するか、iOSでXcodeコンソールを確認します。アプリが起動すると、Hermesは「Hermes VM initialized」といったメッセージを出力します。JavaScriptコードでglobalThis.HermesInternalを確認することもできます— 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 Modules)と完全に互換性があります。さらに、HermesとJSIは一緒に開発され、ペアとして最高のパフォーマンスを提供します。
はい、HermesはiOSとAndroidの両方のプラットフォームをサポートしています。iOSでは、Hermesが標準のJavaScriptCoreを置き換え、同じ利点(高速起動と低メモリ消費)を提供します。
Hermesは大部分のES6+機能をサポートしていますが、制限があります。eval、ジェネレーター、Proxyは利用できません。互換性のために、通常のReact Nativeと同様にBabelトランスパイルを使用することをおすすめします。
Hermesはコンパクトなバイトコードと小さなエンジンサイズにより、アプリサイズを削減します。バイトコードは通常、等価なJSコードより20–30%コンパクトで、エンジン自体のサイズはJSCの~2MBに対して~250KBです。
大部分のライブラリはHermesと互換性があります。ライブラリがeval、Proxyまたは非標準機能を使用している場合は、Hermes互換バージョンがあるかどうか確認してください。Babelプラグインを使用して、サポートされていない構造を置き換えることもできます。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。