メインコンテンツへスキップ

Hermesのデフォルト化

·5分で読めます
Michael Leon
マイケル・レオン
ソフトウェアエンジニア @ Meta

昨年10月、私たちは発表した通り、**すべてのReact NativeアプリでHermesをデフォルトエンジンにする**ための作業を開始しました。

HermesはMeta内のReact Nativeに多大な価値を提供しており、オープンソースコミュニティも恩恵を受けると信じています。Hermesはリソースに制約のあるデバイス向けに設計されており、起動時間、アプリサイズ、メモリ消費量を最適化します。Hermesと他のJSエンジンとの主な違いの1つは、JavaScriptソースコードを事前にバイトコードにコンパイルできることです。このプリコンパイルされたバイトコードはバイナリにバンドルされており、アプリの起動時にインタープリタがこの高価なステップを実行する必要がなくなります。

発表以来、Hermesを改善するために多くの作業が行われてきました。そして今日、React Native 0.70がデフォルトエンジンとしてHermesを搭載して出荷されることをお知らせできることを嬉しく思います。これは、v0.70で開始されるすべての新しいプロジェクトでHermesがデフォルトで有効になることを意味します。7月にロールアウトを控えているため、コミュニティと緊密に連携し、スムーズな移行とすべてのユーザーへの価値提供を確実にしたいと考えています。このブログ投稿では、変更から期待できること、パフォーマンスベンチマーク、新機能などについて説明します。React Native 0.70を待つ必要はなく、これらの手順に従って、既存のReact NativeアプリでHermesを有効にすることができます

なお、新規のReact NativeプロジェクトではHermesがデフォルトで有効になりますが、他のエンジンのサポートは継続されます。

ベンチマーク

アプリ開発者にとって重要な3つの異なる指標(TTI、バイナリサイズ、メモリ消費量)を測定しました。テストにはReact NativeアプリMattermostを使用しました。これらの実験は、2020年のハイエンドハードウェアでAndroidとiOSの両方で実行しました。

  • TTI(time to interactive)とは、アプリが起動してからユーザーが操作できるようになるまでの時間です。このベンチマークでは、アプリのアイコンをタップしてから最初の画面がレンダリングされるまでの時間として定義しています。Mattermostの起動のスクリーン録画も示します。
  • バイナリサイズは、AndroidではAPKサイズ、iOSではIPAサイズとして測定されました。
  • メモリ消費量データは、Mattermostアプリを数分間使用して収集されました。両方のエンジンで同じ操作がアプリ内で実行されました。

Androidベンチマークデータ

すべてのAndroidテストはSamsung Galaxy S20で実行されました。

Android Benchmarking Data

TTIビデオ

Android TTI Video

iOSベンチマークデータ

すべてのiOSテストはiPhone 12 Proで実行されました。

iOS Benchmarking Data

TTIビデオ

iOS TTI Video

起動時間の違いをよりよく示すためのTTIビデオのスロー再生

iOS Slowed Down TTI Video

React Native/Hermes統合

私たちは、長年にわたる互換性の問題と、新しいReact Nativeバージョンをリリースする際の繰り返しの問題を引き起こしてきた、長年の問題に対処しました。React Nativeは、CocoaPodsとnpmを介して配布されるプレビルドバイナリを介してHermesに依存していました。これにより、APIまたはABIの非互換性が発生する可能性がありました。この問題を解決するため、React Native 0.69から、HermesはReact Nativeのすべてのバージョンと並行してビルドされます。これにより、各バージョンのReact Nativeとの完全な互換性が保証されます。これにより、より緊密な統合も実現されます。機能の開発やバグ修正の展開にかかる反復時間が短縮され、Hermesへの大きな変更が正しく行われることをより確実にできるようになります。新しい統合の変更に関する詳細情報はこちらにあります。

iOS Intl

多岐にわたる言語に依存する機能を提供するECMAScript Internationalization APIであるIntlのiOS側実装を完了しました。これは、一部の開発者がHermesを使用することを妨げていた長年のギャップでした。Microsoftとの提携により行われたAndroid実装はReact Native 0.65で出荷されました。React Native 0.70では、開発者は両方のプラットフォームでネイティブサポートを利用できるようになります。

Intlの典型的な実装では、Unicode CLDRのような大きなルックアップテーブルやデータをインポートする必要があります。しかし、これには最大6MBの容量増加という高いコストがかかる可能性があるため、Hermesのバイナリサイズを肥大化させないように、iOS自体が公開するAPIを呼び出すことでIntlを実装しました。これにより、iOSにすでに含まれているすべてのロケールおよび国際化データを活用できます。

進行中の作業

Hermesを進化させ続けるにあたり、コミュニティに私たちの当面の優先事項を伝えたいと考えています。それは、開発者エクスペリエンスの向上と、JavaScript言語機能の不足が原因で誰もHermesの使用を避けないようにすることです。より具体的には、私たちは

  • 開発者がChrome開発ツールのUIから直接サンプリングプロファイラーを実行できるようにする。
  • BigIntのサポートを追加する。これはコミュニティからの長年の要望であり、ポリフィルできないため一部の開発者がHermesを使用できない原因となる可能性があります。
  • 開発者に新しいメモリ管理制御を公開するWeakRefのサポートを追加する。

まとめ

Hermesがデフォルトになることは、長期的な旅の始まりを意味します。私たちは、コミュニティが今後何年にもわたって効率的なアプリを作成できるようになる新機能に取り組んでいます。また、コミュニティがバグ、質問、フィードバック、アイデアなどを投稿するために、私たちのGitHubリポジトリにアクセスすることを奨励しています!Hermes固有の投稿に使用できるhermesラベルを作成しました。