先頃Facebookがオープンソースとして公開したJavaScriptエンジンのHermesの目標は、Androidデバイス上でのReact Native Appsのパフォーマンス向上にある。特に重視されているのが、起動パフォーマンス、ダウンロードサイズ、メモリ消費量だ。Facebookの主張は、Microsoft Officeと、Slackに代わるオープンソースの代替品であるMattermostを使った最初のベンチマークで裏付けられている。
Hermesは、モバイルアプリのパフォーマンスの改善を目指すFacebookの活動から生まれたものだ。Facebookのエンジニアたちが突き止めた重要な要因のひとつに、JavaScriptエンジンそのものがあったことから、携帯電話アプリの制約された環境における最適化が目標とされた。
いくつかの選択肢を検討した結果、Hermesという、新たなJavaScriptエンジンを開発しました。React Nativeアプリに注目することによって、量販デバイスの制限されたメモリ、遅いストレージ、低い計算能力という条件下において、アプリのパフォーマンスが向上するように設計されています。
前述のようにHermesは、アプリが使用可能になるまでに必要な時間(最初のインタラクションまでの時間、TTI)、アプリのダウンロードサイズ(APKサイズ)、メモリ使用率の3つの指標に焦点を当てている。Facebookは、これらのメトリクスを改善するために実施したアーキテクチャ上の重要な決定として、JavaScriptソースコードのプリコンパイル、JITコンパイラの廃止、モバイルOSの制約に対するガベージコレクション、の適合の3つを挙げて説明している。
JavaScriptをバイトコードにプリコンパイルすることには、パフォーマンス上、2つの重要なメリットがある。ひとつは、解析とコンパイルを事前に行うことで、起動時にこれらのタスクに費やされる時間を直接的に節減できることだ。もうひとつは、プリコンパイルフェーズでは時間的制約が緩やかであることから、一般論としてより小さく、より効率的なバイトコードの生成が可能になることだ。コンパイラは関数重複の削除や、文字列テーブルのパッキングなど、プログラム全体の最適化を行うことができる。バイトコードの形式に関して、Hermesのバイトコードは、ファイル全体を事前に読み取らなくても、メモリにマッピングすることが可能になっている。これにより、アクセスの遅いフラッシュメモリでの動作が大幅に改善されると同時に、アプリ変更がメモリの過剰使用によってOSから強制終了させられるリスクを低減できる。
(画像はFacebookブログより)
さらに、Facebookの主張によれば、JITコンパイラの主なメリットは、モバイルアプリでは一般的ではない、CPU集約型のワークロードに向けられている。従って、JITコンパイラを使用しなくても大きな損失はなく、逆にウォームアップ時間やネイティブコードのサイズ、メモリ消費量を低減することが可能になる。
モバイルアプリのための最後のパフォーマンス最適化として、Hermesでは、メモリ使用量が原因でモバイルOSによってアプリケーションが強制終了される可能性を最小限に抑えるガベージコレクション戦略を採用している。これに従い、Hermesのガベージコレクタでは、移動や不要時にOSに返却が可能な、不連続なチャンクにオンデマンドアロケーションを実装することによる、全体的な仮想メモリ消費量の削減を試みている。
前述のように、FacebookとMicrosoftがそれぞれ独自に行った最初のベンチマークでは、3つのすべてのメトリックが大幅な向上を示している。特に、Slackの代替であるMattermostでは、インタラクション時間とアプリケーションサイズが半減し、全体的なメモリ使用率が25%削減された。Microsoft Officeでも、すべての指標において20~25%の範囲でパフォーマンスが改善されている。
(画像はFacebookブログより)
Facebookは、この新しいJavaScriptエンジンのターゲットを、V8の汎用的な代替には置いていない。Nodeやブラウザベースのアプリには、V8が依然として最も適している、という考えだ。iOSアプリはiOS SDKに含まれるJavaScriptエンジンのみを使用するように拘束されているため、Hermesによる最適化の恩恵を受けることができない。この点にも注意が必要だ。