
WebViewのKPI - 測定するべき指標
ネイティブのSplashScreen APIの使用
アプリの起動時のパフォーマンスは、ユーザーエクスペリエンスに影響を与えます。ユーザーは、アプリを起動時したらすぐに何らかの画面が表示されることを期待しています。その表示までの速さを表す指標が、TTFF(最初のフレームまでの時間)です。Vega向けReact NativeのネイティブSplashScreen機能は、画像アセットを使用してアプリ固有のスプラッシュ画面を表示します。アプリを起動すると、ユーザーにこの画面がすぐに表示されます。アプリでは、JavaScriptベースのスプラッシュスクリーンをレンダリングすることに時間を割く必要なく、コンテンツの読み込みとネットワーク呼び出しに集中できます。スプラッシュ画面には、一連のアニメーション画像によるアニメーション効果を含めることができます。
この主要業績評価指標(KPI)は、manifest.tomlファイルで指定されたメインコンポーネントが起動してから、最初のフレームをレンダリングするまでにかかる時間として測定します。

WebViewのスプラッシュ画面
SplashScreenManagerを使用すると、アプリの次の画面に進むまでの画面用に、静的グラフィックスまたはアニメーショングラフィックスを作成できます。SplashScreenは、アプリのパッケージング時に、アプリの起動にデバイスが使用するアセットをバンドルします。SplashScreenを使用すると、アプリ起動時の複雑さがいくらか解消され、アプリで最初のフレームの準備ができるまで起動画面が表示されます。
TTFD(描画完了までの時間)マーカーの実装
Vegaアプリは、アプリライフサイクルの各段階で特定のパフォーマンスマーカーの基準を満たす必要があります。マーカーの1つがTTFDです(前の画像を参照)。アプリが正常に読み込まれ、ユーザーとの対話が可能になったら、TTFDマーカーを満たすようにアプリを最適化します。アプリプロセスが開始される前のクールスタート時も、アプリプロセスが既に実行中であるウォームスタート時と同じパフォーマンスマーカーを満たす必要があります。ウェブアプリでは、ウェブアプリのコンテンツが完全に読み込まれたときに、onLoadコールバックでこのマーカーを実装する必要があります。
ウェブアプリを起動して読み込んだ後、useReportFullyDrawn()メソッドを呼び出します。ラッパーにはonLoadイベントがあり、アプリが起動して準備が整ったときにトリガーされます。また、ウォーム起動中にバックグラウンドからフォアグラウンドに移動したときも、reportFullyDrawn()メソッドを呼び出します。
次のサンプルコードでは、コールドスタート(useReportFullyDrawn())とウォームスタートonLoad(warmStart)の両方の処理でkeplerAppStateを呼び出しています。
ネットワークリクエストの最適化
ウェブアプリの起動パフォーマンスを向上させるには、ネットワークリクエストを最適化する必要があります。HTTPリクエストを最小限に抑えると起動パフォーマンスを改善できます。そのためには、可能な場合はCSSファイルとJavaScriptファイルを結合すること、スプライト画像を使用すること、外部のサードパーティへの依存関係を減らすことが効果的です。また、GzipやBrotliを使用してアセット圧縮を有効にすると、HTML、CSS、JavaScriptなどのテキストベースリソースのペイロードサイズを大幅に削減できます。ただし、画像ファイルは通常既に圧縮されているため、この利点は適用されません。サーバーの応答時間の短縮
高速で応答性の高いユーザーエクスペリエンスを提供するためには、サーバーの応答時間を最適化することが重要です。最も効果的な戦略の1つは、コンテンツ配信ネットワーク(CDN)を使用することです。CDNは、画像、JavaScript、CSSファイルなどの静的アセットを、地理的にユーザーに近いエッジロケーションから提供し、レイテンシを削減します。最初のバイトまでの時間(TTFB)を短縮すると、パフォーマンスが大幅に向上する可能性があります。これは、データベースクエリの改善、ミドルウェアのオーバーヘッドの削減、サーバーロジックの最適化など、バックエンド処理を最適化することで達成できます。 APIの効率性も関係があります。API呼び出しの数を最小限に抑え、適切な場合は結合し、リクエストの重複を回避すると、ネットワークのオーバーヘッドを減らすことができます。コンテンツ配信を高速化するには、サーバーサイドレンダリング(SSR)や静的サイト生成(SSG)の使用を検討してください。これらのウェブテクノロジーは、サーバー上でHTMLを事前にレンダリングしてページの読み込みを高速化し、最初のコンテンツの描画(FCP)を改善します。FCPとは、ブラウザがコンテンツの最初の部分をレンダリングするまでにかかる時間です。また、最も重要なコンテンツを最優先するために、遅延読み込みのテクニックを使用して、重要でないデータや補助的なデータの読み込みを遅らせることもできます。レンダリングとJavaScriptの実行の最適化
高速で応答性の高いウェブアプリを作成するには、レンダリングとJavaScriptの実行を最適化します。重要な方針の1つは、ページの読み込み中に負荷の高い計算や不要なロジックによってメインJavaScriptスレッドがブロックされるのを防ぐことです。メインスレッドがブロックされると、レンダリングが遅延してドロップフレームが発生し、ユーザーエクスペリエンスに悪影響が及ぶ可能性があります。 スレッドがブロックされないようにするには、JavaScriptを軽量に保ち、最初の読み込み時は必要なコードのみを実行します。入力イベント処理に必要なコードのみを実行することもできます。入力ハンドラーは、フレームの完了を妨げたり、不要なレイアウト処理を追加したりする可能性があるため、アプリの滑らかさに影響するパフォーマンスの問題を引き起こすことがあります。そこで、ハンドラーはデバウンスすることをお勧めします。つまり、イベントの値を保存して、次のrequestAnimationFrameコールバックでスタイルの変更を処理します。
ページのレンダリングがブロックされるのを防ぐために、すぐに必要とされないスクリプトは、async属性またはdefer属性を使用して非同期で読み込みます。これにより、レンダリングをブロックするJavaScriptの影響が軽減されます。
transformとwill-changeのようなCSSプロパティを使用してアクセラレーションを有効にします。CSSを通じたGPUアクセラレーションは、レンダリングをGPUにオフロードするために役立ちます。これらの戦略により、ウェブアプリの体感的なパフォーマンスと実際のパフォーマンスが向上します。
JavaScriptを最適化するもう1つの方法として、ウェブワーカーがあります。これにより、スクリプトをバックグラウンドで実行できます。詳細については、ウェブアプリのウェブワーカーに関するベストプラクティスを参照してください。
リソースのキャッシュ
キャッシュを使用すると、ウェブアプリのパフォーマンスと応答性が高まります。クライアント側のキャッシュを有効にするには、JavaScriptファイル、CSS、データ、画像などのリソースに対して適切なCache-Controlヘッダーを設定します。キャッシュにより、ウェブアプリのアセットが保存されて再利用され、何度もダウンロードする必要がなくなります。また、CDNキャッシュを利用すると、ユーザーの近くにあるエッジロケーションから静的コンテンツが提供され、読み込み時間が大幅に短縮される可能性があります。クライアントキャッシュとCDNキャッシュを組み合わせることで、開発者はサーバーの負荷を軽減し、レイテンシを減らし、よりスムーズなエクスペリエンスをエンドユーザーに提供できます。
デバイスのハードウェアデコーダーの使用
最新のVegaデバイスには、メディア再生専用のハードウェアデコーダーが搭載されています。ソフトウェア(CPUベース)デコードの代わりにハードウェアデコードを利用すると、CPU負荷の大幅な削減、メモリ使用量の減少、ビデオ再生の滑らかさの改善という効果が得られ、アプリのパフォーマンスが向上します。 重要性の理由:ソフトウェアデコードは計算コストが高く、ビデオ再生中のドロップフレームの発生、CPUの競合の増加によるほかのアプリ操作の低速化、発熱の上昇によるデバイスのスロットリングの発生、メディアの多いコンテンツを読み込むときの最初のフレームまでの時間(TTFF)の増加といった問題を引き起こす可能性があります。ハードウェアデコーダーでは、この処理が専用のシリコンで実行されるため、CPUがUIレンダリングとアプリロジックに解放されます。 推奨プラクティス: 要素で使用するコーデックは常に、ハードウェアでサポートされる形式にします。Vegaデバイスは、H.264(AVC)、H.265(HEVC)、VP8、VP9のような一般にサポートされるコーデックに対して、ハードウェアアクセラレーションによるデコードをサポートしています(デバイスによって異なります)。ソフトウェアのみの形式よりも、これらの形式を優先的に使用してください。実行時にソフトウェアデコードにフォールバックすることがないように、メディアはデバイスのハードウェアデコーダーでネイティブにサポートされる形式で提供します。ハードウェアデコーダーのリソースには限りがあるため、複数の要素を同時に作成しないでください。可能であれば、アプリ全体でビデオ要素を再利用します。Media Source Extensions(MSE)APIを使用してアダプティブストリーミングを実行する場合は、MediaSource.addSourceBuffer()に渡すセグメント形式とコーデック文字列を、ハードウェアでサポートされるコーデックと一致させる必要があります。再生を初期化する前に、MediaSource.isTypeSupported()を使用してサポートを確認してください。HTMLVideoElement.canPlayType()を使用してハードウェアデコーダーのサポート状況を検出し、必要に応じて適切にフォールバックします。
負荷の高いCSSアニメーションとビデオ再生はGPUリソースを奪い合うため、両者を混在させることは避けてください。再生パフォーマンスに影響を与えずに滑らかなアニメーションを実現するには、ハードウェアアクセラレーションを有効にしたCSS変換を使用します。
スクロールパフォーマンスの向上
アプリのスクロールパフォーマンスを向上させるには、考慮すべき点がいくつかあります。まず、offsetTopやscrollHeightなどのレイアウトプロパティには、スクロールイベントハンドラーから頻繁にアクセスしたり変更を加えたりしないようにします。これらの変更を行うと、レイアウトは毎回再計算されるため、パフォーマンスに影響します。スロットリングやデバウンスのメカニズムを使用して、スクロールイベントの処理頻度を制限することもできます。強制的なリフローを防ぐために、スクロールリスナーの内部では、レイアウトの同期的な読み込みや書き込みを避けることをお勧めします。
ページ上のすべてのコンテンツやスクロールリスト全体をレンダリングするのではなく、表示されている要素や必要な要素のみをレンダリングします。スムーズなスクロールを実現するには、GPUアクセラレーション対応のCSSプロパティを使用することも効果的です。たとえば、CPU負荷の高いtop、left、widthなどのプロパティの代わりに、transformを使用します。
Chrome DevToolsの [レンダリング] タブには、スクロール中に低速な描画や重複する描画が発生しているレイヤーを視覚的に強調表示する機能があります。このツールを使用すると、パフォーマンスのボトルネックを特定し、スクロール動作を最適化できます。

