見出し画像

React Nativeパフォーマンス向上のための基礎知識

こんにちは、外資系企業のエンジニアとして働いています。タロイモともうします。

今回はReact Nativeでパフォーマンスを向上するための基礎知識をまとめてみます。

ネイティブアプリを使う理由

スマホのアプリを作る際、WebView(ブラウザビュー)を使わない理由はネイティブアプリのUIが毎秒60フレーム*の動きを提供してくれるからです。

*60フレームは1秒間のアニメーションに60枚の画像を使うこと

つまり、バターの上を滑るように滑らかな動きを提供してくれることが、ネイティブ言語を使いアプリを作り上げる理由ということです。

フレームの大切さ

iOSデバイスは毎秒60フレームでUIを表示します。このUIを表示するために約16.67ミリ秒がUIシステムに割り当てられます。この16.67ミリ秒以内にフレームを生成するために必要な作業を実行できない場合は、フレーム落ちし、UIは滑らかさを失いカクカクとします。

つまり、凍ったバターの上のようになります。

パフォーマンスの確認

React Nativeでパフォーマンスを確認してみましょう。

SimulatorでShow Perf Monitorを表示します。

スクリーンショット 2020-09-14 22.15.08

1番目のRAMは現在の実行プロセスのメモリ使用量を示しています。

プロセスとは?
プロセスはOSにおけるプログラムの実行単位のことで、プロセスを起動しようとすると、.EXEファイル中に格納されている実行コードやデータ、リソースなどのイメージがメモリ上に展開され、それを呼び出される。
通常、アプリケーションを起動すると1つ以上のプロセスが起動する。
参考:https://www.atmarkit.co.jp/ait/articles/1410/30/news150.html

2番目のJSCはJavaScriptスレッドのメモリ使用量を示しています。

React Nativeは、バックグラウンドのJavaScriptスレッドからiOSのUI要素(ビュー)を生成する。

3番目のViewsは2つの数値がありますが、1行目の数値は現在表示されているビューの数を示しています。2行目の数値はメモリに作成および保存されたビューの数を示しています。

ビューとは?
ビューはUIの基本的な構成要素です。画面上の小さな長方形の要素であり、「テキスト」、「画像の表示」、または「ユーザー入力への応答」などにも使用できます。テキスト行やボタンなど、アプリの最小の視覚要素でさえビューの一種です。ビューの種類によっては、他のビューを含めることができます。

スクリーンショット 2020-09-14 22.33.07

参考:https://reactnative.dev/docs/intro-react-native-components

最後の2つの列は、UIの現在のフレームレート(メインスレッド)とJavaScriptフレームレート(JavaScriptスレッド)を示しています。

例えば、上記の画像では毎秒60フレームでUIを表示し、JavaScriptは毎秒60フレームを実行しています。

これが60フレームより低くなると、パフォーマンスが落ちていることを意味するので、デバッグを行い原因を分析する必要があります。

JSフレームレート(JavaScriptスレッド)

React Nativeアプリでは、ほぼ全ての処理がJavaScriptスレッドで実行されます。

Reactアプリケーションが存在する場所、API呼び出しが行われる場所、タッチイベントが処理される場所などがJavaScriptスレッドで実行されます。

なので上記のパフォーマンスモニターではほとんどの動きはJSフレームレートに影響します。

ボタンを押したりしてみるとJSスレッドのフレームが下がっていることが確認できると思います。

スクリーンショット 2020-09-14 23.13.27

UIフレームレート(メインスレッド)

メインスレッドはあまり使われません。

ScrollViewはメインスレッドで実行されるようです。

確かに上下に何度もスクロールしてみたり、Reloadして再描写してみると、UIフレームレートの値が下がっていることがわかると思います。

スクリーンショット 2020-09-14 23.27.59


(参考)React Nativeの動作プロセス

①アプリの最初の起動時に、メインスレッド(UIフレームレート)が実行を開始し、JSバンドルの読み込みを開始します。

②JavaScriptコードが正常に読み込みされると、メインスレッドはそれを別のJavaScriptスレッド(JSフレームレート)に送信します。

③次にメインスレッドから送られたJavascriptコードを元にReactがレンダリングを開始すると、Reconcilerは「差分」を検知し、新しい仮想DOM(レイアウト)を生成し、別のJavaScriptスレッド(シャドウスレッド)に変更を送信します。

④別のJavaScriptスレッド(シャドウスレッド)はレイアウトを計算し、生成したレイアウトをメインスレッドに送信し、UIがレンダリングされます。

参考:https://www.codementor.io/@saketkumar95/how-react-native-works-mhjo4k6f3


まとめ

今回は、React Nativeのパフォーマンスチューニングをするための基礎知識をまとめてみました。

次回は実際にデバッグを行い、パフォーマンスチューニングの紹介をできたらと思います。

ご精読ありがとうございました。

よろしければサポートお願いします! サポートは、サービスの開発・改良や、記事を書く際の素材費とさせていただきます。 少しでも有益な情報発信をしていけるよう努めてまいります。 是非とも応援よろしくお願いします!!!🙇‍♂️