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

Hermesのデフォルト化

·5分で読めます
Michael Leon
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を待たずにHermesの使用を開始する必要はありません。既存の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国際化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から直接サンプリングプロファイラを実行できるようにする。
  • ポリフィルできないため、一部の開発者がHermesを使用できない原因となる可能性のある、コミュニティからの長年の要望であるBigIntのサポートを追加する。
  • 開発者に新しいメモリ管理制御を公開するWeakRefのサポートを追加する。

まとめ

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