パフォーマンスの計画

ユーザーは、アプリに高い応答性と自然な使用感、そしてバッテリーが消耗しないことを期待しています。 技術的には、パフォーマンスは機能要件ではありませんが、パフォーマンスを機能として扱うことで、ユーザーの期待に応えるのに役立ちます。 目標を指定し、測定することは重要な要因です。 パフォーマンスが重要なシナリオを決定し、優れたパフォーマンスとは何を意味するかを定義します。 次に、プロジェクトの初期とライフサイクル全体で十分な回数の測定を行って、目標を達成できることを確認します。

目標の指定

ユーザー エクスペリエンスは、優れたパフォーマンスを定義するための基本的な方法です。 アプリの起動時間は、ユーザーがパフォーマンスに対する認識に影響を与える可能性があります。 ユーザーは、アプリの起動時間が 1 秒未満が優れている、5 秒未満が良い、5 秒を超える時間が悪いと考える場合があります。

その他のメトリクスは、メモリなどのユーザー エクスペリエンスへの影響は明らかではないものです。 中断中または非アクティブな状態でアプリが終了する可能性は、アクティブなアプリによって使用されるメモリの量と共に増加します。 メモリ使用量が多い場合、システム上のすべてのアプリのエクスペリエンスが低下するというのは一般的なルールであるため、メモリ使用量を目標にすることは妥当です。 ユーザーが認識するアプリの大まかなサイズ (小、中、または大) を考慮してください。 パフォーマンスに関する期待値は、この認識に関連します。 たとえば、大量のメディアを使用しない小さなアプリで、100 MB 未満のメモリを消費することが必要な場合があります。

最初の目標を設定してから、後で修正する方が、目標をまったく持たないことより良いです。 アプリのパフォーマンス目標は、具体的で測定可能であり、以下 3 つのカテゴリに分類される必要があります: ユーザーまたはアプリがタスクを完了するまでの時間 (時間)、ユーザーの操作に応じてアプリが自身を再描画する速度と継続性 (流動性)、また、バッテリ電力を含むシステム リソースをどの程度保てるか (効率)。

時刻

ユーザーがアプリでタスクを完了するためにかかる経過時間の容認できる範囲 (対話式操作クラス) を考えます。 対話式操作クラスごとに、ラベル、認識されるユーザーセンチメント、理想的なおよび最大期間を割り当てます。 いくつかの提案を次に示します。

対話式操作クラス ラベル ユーザーの認識 理想 最大値
高速 最小限の目立った遅延 100 ミリ秒 200 ミリ秒 アプリ バーを表示する、ボタンを押す (最初の応答)
通常 早いですが、高速ではありません 300 ミリ秒 500 ミリ秒 サイズ変更、セマンティック ズーム
レスポンシブ 早くないが、レスポンシブだと感じる 500 ミリ秒 1 秒 別のページに移動する、中断状態からアプリを再開する
起動 競争力のあるエクスペリエンス 1 秒 3 秒 アプリを初めて起動するか、以前に終了した後に起動する
継続的 レスポンシブだと感じなくなった 500 ミリ秒 5 秒 インターネットからファイルをダウンロードする
キャプティブ 長い、ユーザーが切り替える可能性がある 500 ミリ秒 10 秒 Microsoft Store から複数のアプリをインストールする

 

これで、アプリのパフォーマンス シナリオに対話式操作クラスを割り当てることができます。 アプリの特定の時点の参照、ユーザー エクスペリエンスの一部、および対話式操作クラスを各シナリオに割り当てることができます。 食べ物や食事のアプリの例に関するいくつかの提案を次に示します。

シナリオタイム ポイントユーザー エクスペリエンス対話式操作クラス
レシピ ページに移動する 最初の応答ページ切り替えアニメーションの開始高速 (100 ~ 200 ミリ秒)
レスポンシブ材料リストが読み込まれた、画像なしレスポンシブ (500 ミリ秒から 1 秒)
表示完了すべてのコンテンツが読み込まれた、画像が表示される連続 (500 ミリ秒から 5 秒)
レシピを検索する最初の応答検索ボタンをクリックした高速 (100 ~ 200 ミリ秒)
表示完了ローカル レシピ タイトルの一覧が表示された標準 (300 ~ 500 ミリ秒)

ライブ コンテンツを表示する場合は、コンテンツの鮮度の目標も考慮してください。 数秒ごとにコンテンツを更新することが目標ですか? または、コンテンツを数分ごと、数時間ごと、または 1 日に 1 回でも更新することは、許容できるユーザー エクスペリエンスですか?

目標を指定すると、アプリをテスト、分析、最適化できるようになりました。

流動性

アプリの具体的な測定可能な流動性の目標は次を含めることができます:

  • 画面の再描画の停止と開始 (グリッチ) はありません。
  • アニメーションは、1 秒あたり 60 フレーム (FPS) でレンダリングされます。
  • ユーザーがパン/スクロールすると、アプリは 1 秒あたり 3 ~ 6 ページのコンテンツを表示します。

効率

アプリの具体的な測定可能な効率性の目標は次を含めることができます:

  • アプリのプロセスでは、CPU 使用率は N 以下であり、メモリ使用量 (MB) は常に M 以下です。
  • アプリが非アクティブな場合、 NM は、アプリのプロセスに対してゼロになります。
  • アプリは、バッテリ電源で X 時間積極的に使用することができます。アプリが非アクティブな場合、デバイスは Y 時間の充電を保持します。

パフォーマンスのためにアプリを設計する

これで、パフォーマンス目標を使用して、アプリの設計に影響を与えることができます。 食べ物と食事のアプリの例を使用して、ユーザーがレシピ ページに移動した後、レシピの名前が最初にレンダリングされ、食材が延期され、画像の表示がさらに延期されるように、項目を段階的に更新することを選択できます。 これにより、パン/スクロール中に応答性と滑らかな UI が維持され、対話式操作後に UI スレッドが追いつくことができるペースで完全な忠実度なレンダリングが行われます。 考慮すべきその他の側面を次に示します。

UI

  • XAML マークアップ を最適化することで、アプリの UI (特に初期ページ) の各ページの解析と読み込み時間とメモリ効率を最大化します。 簡単に言うと、必要になるまで UI とコードの読み込みを延期します。
  • ListViewGridView の場合は、すべての項目を同じサイズにし、可能な限り多くの ListView と GridView の最適化手法 を使用します。
  • UI をマークアップの形式で宣言します。これは、フレームワークがコード内で命令的に構築するのではなく、チャンクで読み込んで再利用することができます。
  • ユーザーが UI 要素を必要とするまで、UI 要素の作成を遅らせます。 x:Load 属性を参照してください。
  • テーマの切り替えとアニメーションをストーリーボードに設定されたニメーションより優先させます。 詳しくは、「アニメーションの概要」を参照してください。 ストーリーボードに設定されたアニメーションでは、画面を一定に更新する必要があり、CPU とグラフィックス パイプラインをアクティブな状態に保つ必要があります。 バッテリーを保持するために、ユーザーがアプリを操作していない場合は、アニメーションを実行しないでください。
  • 読み込むイメージは、GetThumbnailAsync メソッドを使用して、表示するビューに適したサイズで読み込む必要があります。

CPU、メモリ、電源

  • 優先順位の低い作業を優先順位の低いスレッドやコアで実行するようにスケジュールします。 「非同期プログラミング」の、Dispatcher プロパティ、および CoreDispatcher をクラス参照してください。
  • 中断時にコストが高いリソース (メディアなど) を解放することで、アプリのメモリ占有領域を最小限に抑えます。
  • コードのワーキング セットを最小限に抑えます。
  • 可能な限り、イベント ハンドラーの登録を解除し、UI 要素を逆参照することで、メモリ リークを回避します。
  • バッテリのために、データのポーリング、センサーのクエリ、アイドル時の CPU での作業のスケジュールを設定する頻度は控えめにします。

データ アクセス

  • 可能であれば、コンテンツをプリフェッチします。 自動プリフェッチについては、ContentPrefetcher クラスを参照してください。 手動プリフェッチについては、 Windows.ApplicationModel.Background 名前空間と MaintenanceTrigger クラスを参照してください。
  • 可能であれば、アクセスにコストがかかるコンテンツをキャッシュします。 LocalFolderLocalSettings プロパティを参照してください。
  • キャッシュ ミスの場合は、アプリがまだコンテンツを読み込んでいることを示すプレースホルダー UI をできるだけ早く表示します。 プレースホルダーからライブ コンテンツへの切り替えは、ユーザーには問題のない方法で行います。 たとえば、アプリがライブ コンテンツを読み込む際に、ユーザーの指またはマウス ポインターの下のコンテンツの位置を変更しないでください。

アプリの起動と再開

アダプティブ UI と向き

  • VisualStateManager クラスを使用します。
  • 必要な処理だけをすぐに完了し、負荷の大きなアプリの作業は後回しにします。処理を完了し、アプリの UI がトリミングされた状態で表示されるまでに 200 ~ 800 ミリ秒かかります。

パフォーマンス関連の設計が整ったら、アプリのコーディングを開始できます。

パフォーマンスのためのインストルメント化

コードを作成するときに、アプリの実行中に特定の時点でメッセージとイベントをログに記録するコードを追加します。 後でアプリをテストするときに、Windows パフォーマンス レコーダーや Windows Performance Analyzer などのプロファイリング ツール (どちらも Windows パフォーマンス ツールキット に含まれています) を使用して、アプリのパフォーマンスに関するレポートを作成して表示できます。 このレポートでは、これらのメッセージとイベントを検索して、レポートの結果をより簡単に分析できます。

ユニバーサル Windows プラットフォーム (UWP) には、Event Tracing for Windows (ETW) に基づくログ記録 API が用意されており、一緒に豊富なイベント ログ記録とトレース ソリューションを提供します。 Windows.Foundation.Diagnostics 名前空間の一部である API には、FileLoggingSessionLoggingActivityLoggingChannelLoggingSession クラスが含まれています。

アプリの実行中に特定の時点でレポートにメッセージを記録するには、LoggingChannel オブジェクトを作成し、次のようにオブジェクトの LogMessage メソッドを呼び出します。

// using Windows.Foundation.Diagnostics;
// ...

LoggingChannel myLoggingChannel = new LoggingChannel("MyLoggingChannel");

myLoggingChannel.LogMessage(LoggingLevel.Information, "Here' s my logged message.");

// ...

アプリの実行中にレポートの開始イベントと停止イベントを一定期間ログに記録するには、LoggingActivity オブジェクトを作成し、次のようにオブジェクトの LoggingActivity コンストラクターを呼び出します。

// using Windows.Foundation.Diagnostics;
// ...

LoggingActivity myLoggingActivity;

// myLoggingChannel is defined and initialized in the previous code example.
using (myLoggingActivity = new LoggingActivity("MyLoggingActivity"), myLoggingChannel))
{   // After this logging activity starts, a start event is logged.
    
    // Add code here to do something of interest.
    
}   // After this logging activity ends, an end event is logged.

// ...

ログのサンプルも参照してください。

アプリをインストルメント化すると、アプリのパフォーマンスをテストして測定できます。

パフォーマンス目標に対するテストと測定

パフォーマンス計画の一部として、パフォーマンスを測定する開発中のポイントを定義します。 これは、プロトタイプの作成、開発、デプロイのどちらで測定するかによって異なる目的で機能します。 プロトタイプ作成の初期段階でパフォーマンスを測定することは非常に価値があるので、意味のある作業を行うコードがあればすぐに行うことをお勧めします。 早期測定では、重要なコストがアプリ内のどこにあるかを把握し、設計上の判断を通知します。 これにより、アプリのパフォーマンスとスケーリングが高くなります。 一般に、前よりも後で設計を変更する方がコストがかかります。 製品サイクルの後半でパフォーマンスを測定すると、直前のハックやパフォーマンスの低下が発生する可能性があります。

これらの手法とツールを使用して、元のパフォーマンス目標に対してアプリがどのようにスタックアップするかをテストします。

  • オールインワン PC、デスクトップ PC、ノート PC、Ultrabook、タブレット、その他のモバイル デバイスなど、さまざまなハードウェア構成に対してテストします。
  • さまざまな画面サイズに対してテストします。 画面サイズを広くすると、より多くのコンテンツを表示できますが、そのすべての追加コンテンツを取り込むことはパフォーマンスに悪影響を与える可能性があります。
  • できる限り多くのテスト変数を排除します。
    • テスト デバイスでバックグラウンド アプリをオフにします。 これを行うには、Windows の [スタート] メニューで [設定]、>[個人用設定]>[ロック画面] の順に選択します。 アクティブな各アプリを選択し、[なし] 選択します。
    • アプリをテスト デバイスにデプロイする前に、リリース構成でビルドしてネイティブ コードにコンパイルします。
    • 自動メンテナンスがテスト デバイスのパフォーマンスに影響しないようにするには、手動でトリガーし、完了するまで待ちます。 Windows の [スタート] メニューで、[セキュリティとメンテナンス] を検索します。 [メンテナンス] 領域の [自動メンテナンス] で、[メンテナンス開始] を選択し、[進行中のメンテナンス状態] が変わるのを待ちます。
    • アプリを複数回実行して、ランダムなテスト変数を排除し、一貫性のある測定を実現します。
  • 電力の可用性の低下をテストします。 ユーザーのデバイスの能力は、開発用コンピューターよりも大幅に低下する場合があります。 Windows は、モバイル デバイスなどの低電力デバイスを念頭に置いて設計されました。 プラットフォーム上で実行されるアプリは、これらのデバイスで適切に動作するようにする必要があります。 ヒューリスティックとして、低電力デバイスがデスクトップ コンピューターの約 4 分の 1 の速度で実行されることを期待し、それに応じて目標を設定します。
  • Microsoft Visual Studio や Windows Performance Analyzer などのツールを組み合わせて使用して、アプリのパフォーマンスを測定します。 Visual Studio は、ソース コードのリンクなど、アプリに重点を置いた分析を提供するように設計されています。 Windows Performance Analyzer は、システム情報、タッチ操作イベントに関する情報、ディスク入出力 (I/O) とグラフィックス処理装置 (GPU) のコストに関する情報の提供など、システムに重点を置いた分析を提供するように設計されています。 どちらのツールもトレース キャプチャとエクスポートを提供し、共有トレースと事後分析トレースを再度開くことができます。
  • 認定を受けるためにアプリをストアに提出する前に、Windows アプリ認定キット テストの「パフォーマンスのテスト」セクションと UWP アプリのテスト ケースの「パフォーマンスと安定性」セクションの説明に従って、パフォーマンス関連のテスト ケースをテスト プランに組み込みます。

詳細については、これらのリソースとプロファイリング ツールを参照してください。

パフォーマンス テストの結果に応答する

パフォーマンス テストの結果を分析した後、次に例を示す変更が必要かどうかを判断します:

  • アプリの設計上の決定を変更するか、コードを最適化する必要がありますか?
  • コード内のインストルメンテーションを追加、削除、または変更する必要がありますか?
  • パフォーマンス目標を修正する必要がありますか?

変更が必要な場合は、変更を行い、インストルメント化またはテストに戻って繰り返します。

最適化

ほとんどの時間が費やされるアプリのパフォーマンスクリティカルなコード パスのみを最適化します。 プロファイリングによって、どちらがそれに当てはまるかがわかります。 多くの場合、適切な設計プラクティスに従うソフトウェアを作成することと、最高の最適化で実行するコードを記述することにはトレードオフがあります。 一般に、パフォーマンスが懸念されない領域では、開発者の生産性と優れたソフトウェア設計を優先することが良いとされています。