アプリのパフォーマンスを計画および測定する

ユーザーは、アプリの応答性が維持され、自然に感じられ、バッテリーを消耗しないことを期待しています。 技術的には、パフォーマンスは機能しない要件ですが、パフォーマンスを機能として扱うと、ユーザーの期待に応えるのに役立ちます。 目標を指定し、結果を測定します。これらは重要な要因です。 パフォーマンスが重要なシナリオを決定し、優れたパフォーマンスの意味を定義し、プロジェクトのライフサイクル全体を通して早期および頻繁に測定し、目標を達成できることを確信します。

目標を指定する

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

その他のメトリックは、メモリなどのユーザー エクスペリエンスに対する明らかな影響を受けにくいです。 中断中または非アクティブな状態でアプリが終了する可能性は、アクティブなアプリが使用するメモリの量と共に増加します。 メモリ使用量が多い場合、システム上のすべてのアプリのエクスペリエンスが低下するため、メモリ消費の目標が妥当です。

具体的で測定可能な初期目標を設定します。 次の 3 つのカテゴリに分類されます。

  • 時間 — ユーザーまたはアプリがタスクを完了するのにかかる時間
  • 流動性 - ユーザーの操作に応じてアプリ自体を再描画する速度と継続性
  • 効率 — バッテリ電力を含むシステム リソースをどの程度節約できるか

時間

ユーザーが自分のタスクを完了するために許容できる経過時間 (相互作用クラス) の範囲を考えてみましょう。

インタラクションクラス ユーザーの認識 理想 Maximum Examples
速い ほとんど気付かれない遅延 100 ミリ秒 200 ミリ秒 アプリ バーを表示します。ボタンを押す (最初の応答)
普通 クイックですが、高速ではありません 300 ミリ秒 500 ミリ秒 サイズ変更; セマンティック ズーム
応答性が高い 迅速ではありませんが、応答性が高い 500 ミリ秒 1 秒 別のページに移動します。アプリを再開する
開始 競争力のあるエクスペリエンス 1 秒 3 秒 初めてアプリを起動する
継続的 応答性を感じなくなった 500 ミリ秒 5 秒 インターネットからファイルをダウンロードする
キャプティブ 長い; ユーザーは離脱する可能性がある 500 ミリ秒 10 秒 ストアから複数のアプリをインストールする

アプリのパフォーマンス シナリオに対話クラスを割り当てます。 シナリオごとに、アプリの特定の時点の参照、ユーザー エクスペリエンスの一部、および対話クラスを割り当てます。

流動

アプリの具体的な測定可能な流動性の目標は次のとおりです。

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

Efficiency

アプリの具体的な測定可能な効率目標は次のとおりです。

  • アプリの CPU 使用率がターゲット値以下で、メモリ使用量 (MB) が常にターゲット以下である
  • アプリが非アクティブな場合、CPU とメモリの使用は最小限です
  • アプリは、バッテリ電源の目標時間数に対してアクティブに使用できます

パフォーマンスを向上させるためにアプリを設計する

パフォーマンス目標を使用して、アプリの設計に影響を与えます。 次の点を考慮してください。

UI

  • XAML マークアップを最適化することで、各ページの解析と読み込み時間とメモリ効率を最大化します。 必要になるまで UI とコードの読み込みを延期します。
  • ListViewGridViewでは、すべての項目を同じサイズにし、できるだけ多くの最適化手法を使用します。
  • コードで命令型に構築するのではなく、マークアップで UI を宣言します。
  • ユーザーが x:Load 属性を使用して UI 要素を必要とするまで、UI 要素の作成を遅らせる。
  • ストーリーボード化されたアニメーションよりも、テーマの切り替えとアニメーションを優先してください。 ストーリーボードに設定されたアニメーションでは、画面を一定に更新し、CPU とグラフィックス パイプラインをアクティブな状態に保つ必要があります。
  • 表示するビューに適したサイズで画像を読み込みます。

CPU、メモリ、および電源

  • 優先順位の低いスレッドで優先順位の低い作業をスケジュールします。 非同期プログラミングDispatcherQueue クラスを参照してください。
  • 不要な場合は、高価なリソース (メディアなど) を解放して、アプリのメモリ占有領域を最小限に抑えます。
  • 可能な限り、イベント ハンドラーの登録を解除し、UI 要素を逆参照することで、メモリ リークを回避します。
  • バッテリ効率を高める場合は、データのポーリング、センサーのクエリ、アイドル時の CPU での作業のスケジュールを設定する頻度を控えめにしてください。

データ アクセス

  • 可能であれば、コンテンツをプリフェッチします。
  • アクセスコストの高いコンテンツをキャッシュします。
  • キャッシュ ミスの場合は、アプリがまだコンテンツを読み込んでいることを示すプレースホルダー UI をできるだけ早く表示します。

パフォーマンス測定用計測器

コードを作成するときに、アプリの実行中に特定の時点でメッセージとイベントをログに記録するコードを追加します。 後で、Windows パフォーマンス レコーダーやWindows パフォーマンス アナライザー (両方ともWindows Performance Toolkitに含まれる) などのプロファイリング ツールを使用して、アプリのパフォーマンスに関するレポートを作成して表示します。

Windowsでは、豊富なイベント ログとトレース ソリューションを提供するイベント トレーシング for Windows (ETW) によってサポートされるログ記録 API が提供されます。 Windows.Foundation.Diagnostics 名前空間の API には、FileLoggingSessionLoggingActivityLoggingChannel、および LoggingSession などのクラスが含まれます。

// using Windows.Foundation.Diagnostics;

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

一定期間の開始イベントと停止イベントをログに記録するには:

LoggingChannel myLoggingChannel = new LoggingChannel("MyLoggingChannel");
LoggingActivity myLoggingActivity;

using (myLoggingActivity = new LoggingActivity("MyLoggingActivity", myLoggingChannel))
{
    // A start event is logged when the activity begins.
    // Add code here to do something of interest.
}
// An end event is logged when the activity ends.

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

次の手法とツールを使用して、パフォーマンス目標に対するアプリのスタックアップ方法をテストします。

  • デスクトップ、ノート PC、Ultrabook、タブレットなど、さまざまなハードウェア構成に対してテストします。
  • さまざまな画面サイズに対してテストします。 画面が広いほどコンテンツが多く表示され、パフォーマンスに悪影響を与える可能性があります。
  • できる限り多くのテスト変数を排除します。
    • テスト デバイスでバックグラウンド アプリをオフにします。
    • テスト デバイスにアプリをデプロイする前に、リリース構成でアプリをビルドします。
    • アプリを複数回実行して、ランダムなテスト変数を排除し、一貫性のある測定を確保します。
  • 電力の可用性の低下をテストします。 ユーザーのデバイスの能力は、開発用コンピューターよりも大幅に少ない場合があります。
  • Visual Studio診断ツールやWindows パフォーマンス アナライザーなどのツールを組み合わせて使用して、アプリのパフォーマンスを測定します。

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

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

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

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

Optimize

最も多くの時間が費やされるアプリ内のパフォーマンスクリティカルなコード パスのみを最適化します。 プロファイルによって、これらの領域が示されます。 多くの場合、適切な設計プラクティスと、最高の最適化で実行されるコードの間にはトレードオフがあります。 パフォーマンスが問題にならない領域では、開発者の生産性と優れたソフトウェア設計に優先順位を付けます。