[翻訳] Ionic vs React Nativeでパフォーマンス比較。実際どれだけ違う？！

この記事は、 [Ionic Framework / Capacitor / Stencil Advent Calendar 2022](https://qiita.com/advent-calendar/2022/ionic_jp) の2日目の記事です。

この記事は、Ionic Blogで公開された [Ionic vs. React Native: Performance Comparison](https://ionic.io/blog/ionic-vs-react-native-performance-comparison) の翻訳記事です。記事の翻訳を快諾してくれたIonic Teamと著者のConnerに感謝します。
なお、記事内の動画はアニメーションGifとなっており、元記事のvideoと比べて画質が落ちます。きれいな映像でみたい人は、アニメーションGif下にあるリンクから元動画を閲覧ください。

---

IonicとReact Nativeがクロスプラットフォームアプリケーション開発のエコシステムで競合していることは周知の事実です。

ネットで検索すれば、この2つのクロスプラットフォームソリューションを比較する記事が無数にヒットします。これらの記事の中で、React Nativeの方が優れてると主張する一部の人は、一方のプラットフォームを選択する最大の理由として、しばしばパフォーマンスに注目します。React Nativeは、（IonicのようにブラウザでUIをレンダリングするのではなく）ネイティブのUIコントロールをレンダリングするため、より高速でなければならないというのが、彼らの前提です。

しかし、問題は、そのような説明では解決できないことです。これらの説明はいずれも、実際のパフォーマンス指標を中心に据えているようには見えません。React Nativeは「よりネイティブ」であり、そのためより優れたパフォーマンスを発揮するという認識のみに基づいているようです。

では、React Nativeの性能は高いのでしょうか？私たちは、同じ機能セットを持つ競合アプリケーションを作成し、まったく同じiPhone 11 Pro Maxで独自のテストをいくつか実行することにしました。その結果を見てみましょう。

# IonicとReact Nativeの比較

まず、IonicやReact Nativeをこれから知ろうという方のために、両者のアプローチや基本的なアーキテクチャがどう違うのかを簡単にまとめておきます。

Ionicは、Web技術を活用してアプリケーションを提供するという哲学に全面的に賛同しています。一方、React NativeもJavaScriptを使って動作しますが、プラットフォーム固有のユーザーインターフェース制御のオーケストレーションという名目で実行されます。どちらのプラットフォームも、プラグインとカスタムネイティブコードによって、完全なネイティブアクセスを備えた [本物のネイティブアプリ](https://medium.com/@maxlynch/cordova-ionic-apps-are-native-apps-64f9e1a995d9) を作成します。

IonicとReact Nativeの違いについて詳しく知りたい方は、 [比較ガイド](https://ionic.io/resources/articles/ionic-react-vs-react-native) をご覧ください。

# 起動時間

アプリケーションのロードにかかる時間は、パフォーマンスを測定するための日常的な指標です。ブートタイムには、コールドブートタイムとウォームブートタイムの2つの見方があります。コールドブート時間は、オペレーティングシステムが完全にリブートされた状態で、アプリに関して何もキャッシュされていない状態で測定されます。一方、ウォームブート時間は、アプリケーションが強制終了され、バックグラウンドで実行されなくなったときに適用されますが、オペレーティングシステムにキャッシュが残っている可能性があります。

React NativeとIonicは、コールドブートタイムが約1.5秒、ウォームブートタイムが約1秒となりました。IonicとReact Nativeの起動時間を並べて見てみましょう。

![b5317558baa2167215f477ecf2459295.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100460/2c98e837-d80e-2664-f91e-5ebc36ad48cb.gif)

> スムーズな動画は [こちら](https://ionic.io/blog/wp-content/uploads/2022/03/Ionic-vs-RN-demos-launch-new.mp4) をご確認ください

React Nativeが圧倒的に速いという人は、Ionicと比較して、起動時のパフォーマンスが大幅に向上すると主張しています。しかし、それは事実ではありません。ビデオでは、アプリケーションのロードスピードがほぼ同じであることが紹介されています。React Nativeが少し優勢と見るなら、Ionicを候補から外すほどの実質的な差はないでしょう。React Nativeも速いですが、Ionicも速いです。

# スムーズなスクロール

一般的なパフォーマンスに関する議論は、Web Nativeアプリケーションは本質的にレンダリングが遅いという概念と結びついているようです。しかし、このテーマについての事実は次の動画がそれを物語っています。

![db8f1b2bd22825a460acc21fe0806975.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100460/e4411e14-562b-5d84-ea10-e59a188eeac3.gif)

> スムーズな動画は [こちら](https://ionic.io/blog/wp-content/uploads/2022/03/Ionic-vs-RN-demos-scrolling.mp4) をご確認ください

一般に、アニメーションが滑らかに見える速度は60fps（frames per second）と言われています。上の動画では、それを完璧に実証しています。スクロール中のレンダリングを実行する間、IonicアプリケーションとReact Nativeアプリケーションの両方が、約16.67ミリ秒、あるいはそのすぐ下の時間をかけて作業を続けています。これにより、ユーザーは "フレームドロップ" の感覚を味わうことはありません。

![rn-fps-cropped.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100460/a45731a3-9af2-c21d-4fe3-1152193a1901.png)

途切れ途切れのユーザーエクスペリエンスは、単にウェブを選択しただけで見られるものではありません。Webは高速であり、Web Nativeアプリケーションも高速です。もちろん、React Nativeアプリケーションも高速です。動画では、2500人の従業員のリストをリストビューに読み込んでいます。各アプリに適切な技術を適用することで、リストはラグなくスクロールを続けています。項目は遅延なく読み込まれ、エクスペリエンスもスムーズです。これは、どちらのクロスプラットフォーム開発プラットフォームを選ぶべきかの良い指標にはならないことは言うまでもありません。どちらのアプローチも、驚くほどうまく機能します。

# ネイティブなトランジション

Web Nativeアプリケーションを取り巻くもう一つの懸念は、そのWebファーストのアプローチにより、ユーザーがアプリケーション内で行うトランジションに関して、ネイティブの感覚が失われるのではないかということです。簡単な例としては、ユーザーがアプリケーションの経路に沿って詳細画面に移動し、戻ってくるときに発生する「プッシュ」と「ポップ」のアニメーションが挙げられます。

これは不正確な推測です。Ionic SDKは、開発者が選択したフロントエンドフレームワークと一緒に、これらのユーザーエクスペリエンスパラダイムを組み込んでリリースすることができます。このようなエレガントな遷移は、ネイティブのUIコントロールをオーケストレーションするフレームワークだけが実現できることではありません。ウェブでも可能なのです。ご覧ください。

![14a220a530b2083868032baa699d2aea.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100460/b3a4d988-b4d0-f623-1fb2-3d2625e2b262.gif)


> スムーズな動画は [こちら](https://ionic.io/blog/wp-content/uploads/2022/03/Ionic-vs-RN-demos-transitions.mp4) をご確認ください

# プラットフォーム固有のスタイリングか、統一されたスタイリングか

最近のモバイル アプリケーションに期待されるのは、OS を問わずアプリケーション内で同じスタイリングを採用することなのかどうか、まだ判断がつきません。多くの人々は、私たちが慣れ親しんでいるプラットフォーム固有のスタイルが依然として標準であるという考え方に賛同しています。また、アプリケーションは純粋にブランドであるべきで、消費されるオペレーティングシステムに関係なく同じように見えるべきだという考え方に傾きつつある人々もいます。

Ionicは、この議論に関係なく、開発者をサポートします。IonicのUIツールキットに含まれる [Adaptive Styling](https://ionicframework.com/docs/core-concepts/fundamentals#adaptive-styling) は、コンポーネントがネイティブの挙動とまったく同じように見えることを意味します。AndroidのMaterial DesignとAppleのCupertino Designに自動的に対応し、どのプラットフォームでアプリが動作しているかによって異なります。これらはすべて、すぐに使える状態で提供されるため、設定は一切必要ありません。しかし、オペレーティングシステムに関係なく、アプリケーションのコンポーネントを同じように見せたい場合は、公開されている [CSS変数](https://ionicframework.com/docs/theming/css-variables) を使用して、標準をオーバーライドして、ブランド固有のスタイルを作成することができます。

React Nativeの方が優れた開発ツールであると主張する人たちの中には、ネイティブのUIコンポーネントをオーケストレーションすることが、真のネイティブのルック＆フィールを実現する唯一の方法であるという考えを用いています。これは、真実から遠く離れたものではありません。上記の動画をスクロールして戻ってくると、ラベルがなければ、その例がIonicで作られたのかReact Nativeで作られたのか判断するのは難しいことに注意してください。

# コードの実行

過去 15 年間の JavaScript における最大の革新のひとつは JavaScript のジャストインタイム (JIT) コンパイルで、解釈された JavaScript を実行時にネイティブのマシンコードに変換し、実行時の性能とエネルギー消費を劇的に改善しました。有名なところでは、chrome を動かす V8 エンジンと Safari を動かす Nitro エンジンが、ブラウザとウェブアプリケーションの能力を再定義する、まったく新しいカテゴリのアプリケーションに JavaScript をもたらしました。

しかし、JITコンパイルはランタイムにネイティブコードを生成して実行する必要があるため、セキュリティ上の問題があります。これらの問題を軽減するため、ベンダーはサンドボックス化されたブラウザ環境で実行されるJavaScriptに対してのみJITコンパイルを有効にしています。例えばモバイルデバイスでは、JavaScriptコードはWKWebViewのようなWeb Viewで実行されているときのみJITエンジンにアクセスすることができます。つまり、Ionicアプリは常にJITエンジンで実行されます。React NativeのようなJavaScriptCoreやHermesを使用するアプリは、JITエンジンにアクセスすることができません。

これがIonicとReact Nativeの最も大きなパフォーマンスの違いの1つです。JITコンパイルを行わないエンジンは、JavaScriptの実行に関して著しくパフォーマンスが低下することが、 [QuickJS Benchmark](https://bellard.org/quickjs/bench.html) の結果などの公開されているデータで示されています。このデータが端的に示すように、JITコンパイルを行わない場合、JavaScriptの実行速度がかなり遅くなり、次のセクションで示すようにエネルギー消費量がかなり高くなります。

# CPU消費量とエネルギーへの影響

パフォーマンスを別の角度から見ると、これら2つのハイブリッドモバイルアプリケーションのCPU消費パフォーマンスについて考えることができます。また別の興味深い結果が表れています。以下のスクリーンショットは、Xcodeから両方のアプリケーションを実行し、従業員リストビューをスクロールしているときに撮影されたものです。

![react-cpu-usage-cropped.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100460/61dbec64-ea4c-0cb8-5858-954d57797da4.png)

これらの画像から、IonicアプリケーションはReact NativeアプリケーションよりもはるかにCPU負荷が低いことがわかります。最高でReact Nativeアプリケーションは200%近いCPUを使用していたのに対し、Ionicは10%以上しか使用していません。この理由は、Ionicハイブリッドアプリは、React Nativeで構築されたようなJavaScriptCoreを使用するハイブリッドアプリよりも、WKWebView内の前述の高速なJSエンジンにアクセスできるためです。外から見ると、これらのアプリケーションはどちらもスムーズに動作しているように見えますが、フードの下では、React Native アプリケーションを実行するためにマシンがかなり激しく働いています。

CPU消費量の指標を見ると、React NativeアプリケーションはIonicアプリケーションよりもかなり多くの負荷をデバイスにかけていることがわかります。

![rn-energy-impact-cropped.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100460/727b05c3-41ee-ef6b-8e49-39f667994bb7.png)

再びリストをスクロールすると、Ionicは「High Energy Impact」の範囲に入り、React Nativeは「Very High Energy Impact」の範囲にさらに上昇しました。アプリがアイドル状態でないときにこれらの範囲を見ることは重要でした。なぜなら、ユーザーが何らかのアクションを実行せずにアプリケーションとやり取りする時間は、はるかに少ないからです。アプリケーションのエネルギー消費量が使用中ずっと高いままだと、バッテリーを消耗することになります。競合する例から、Ionicアプリケーションは、デバイスの全体的なバッテリー寿命に与える影響が小さいと考えられます。

# まとめ

React Nativeは、本当に素晴らしいアプリケーションを構築することができる素晴らしいプラットフォームです。しかし、React Nativeがより良いパフォーマンスを提供するという「神話」は、まさにその通り、神話なのです。そのことを証明するには、例を挙げるだけで十分でしょう。Ionicアプリケーションは、ネイティブアプリケーションと同じように高速で、パフォーマンスが高く、ルック＆フィールも同じです。

私たちの見解は、一方のソリューションを選択する理由として、「パフォーマンス」を使わないでください。どちらのソリューションも、ネイティブアプリケーションのようなルック＆フィールを備えたハイパフォーマンスなアプリケーションを提供します。むしろ、それぞれのプラットフォームで遊んでみて、自分にとって最適で、より簡単で楽しいものを選びましょう。また、ビジネスをサポートするミッションクリティカルなアプリを作る場合は、Ionicだけが提供する [プロフェッショナルサポート](https://ionicframework.com/blog/who-is-going-to-support-your-next-mobile-app-project-hint-not-react-native-or-flutter/) へのアクセスや [エンタープライズサポート](https://ionic.io/enterprise) などを検討してみてください。

いずれにせよ、どのツールを選んでも、アプリが市場でどのように機能するかは、選んだツールよりも、あなたのアイデアの良さとその実行力に左右されることは間違いないでしょう。

## さぁ、はじめよう
Ionicはインストールが簡単で、すぐに使い始めることができます。 [今すぐクロスプラットフォームアプリケーションを作りましょう](https://ionicframework.com/start)