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を表示します。
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の基本的な構成要素です。画面上の小さな長方形の要素であり、「テキスト」、「画像の表示」、または「ユーザー入力への応答」などにも使用できます。テキスト行やボタンなど、アプリの最小の視覚要素でさえビューの一種です。ビューの種類によっては、他のビューを含めることができます。
参考: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スレッドのフレームが下がっていることが確認できると思います。
UIフレームレート(メインスレッド)
メインスレッドはあまり使われません。
ScrollViewはメインスレッドで実行されるようです。
確かに上下に何度もスクロールしてみたり、Reloadして再描写してみると、UIフレームレートの値が下がっていることがわかると思います。
(参考)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のパフォーマンスチューニングをするための基礎知識をまとめてみました。
次回は実際にデバッグを行い、パフォーマンスチューニングの紹介をできたらと思います。
ご精読ありがとうございました。