mcpField
P
performance-profiling

performance-profiling

github.com/rshankrasテスト・品質84482 回インストール14 週間前に更新
リポジトリ

performance-profiling について

Appleプラットフォームのアプリ開発者向けパフォーマンス分析ガイドです。Instruments、Xcode診断、MetricKitを使い、応答性・メモリ・起動時間・エネルギーの調査手順と修正パターンを扱います。

主な機能

  1. 01CPU・メモリ・起動・電力の分析
  2. 02問題に応じた分析ツールの選択
  3. 03分析手順と修正パターンの提示
  4. 04MetricKitによる本番環境の監視
  5. 05チェックリストによる性能確認

活用シーン

  1. 01UIのハングやフレーム落ちの調査
  2. 02メモリリークや増加の特定
  3. 03アプリ起動時間の最適化
  4. 04電池消費や熱問題の診断

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/rshankras/claude-code-apple-skills --skill performance-profiling

インストール後、Claude Code で/performance-profilingを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

energy-diagnostics.md
hitches.md
launch-optimization.md
memory-profiling.md
time-profiler.md

詳細

パフォーマンスのプロファイリング

Instruments、Xcode の診断機能、MetricKit を使用した、Apple プラットフォームアプリのプロファイリングに関する体系的なガイドです。CPU、メモリ、起動時間、エネルギーの分析と、実践的な修正パターンを取り上げます。

このスキルが有効になる条件

ユーザーが次のような場合に、このスキルを使用します。

  • アプリのハング、カクつき、フレーム落ちを報告している
  • CPU 使用率をプロファイリングしたり、処理の集中するコードパスを特定したりする必要がある
  • メモリリーク、高いメモリ使用量、または OOM クラッシュが発生している
  • アプリの起動時間を最適化したい
  • バッテリーやエネルギーへの影響を減らす必要がある
  • Instruments、Time Profiler、Allocations、または Leaks について質問している
  • コードに os_signpost やパフォーマンス測定を追加したい
  • App Store の審査に備えて、パフォーマンスを検証する必要がある

判断ツリー

What performance problem are you investigating?
│
├─ App hangs / unresponsive to taps / slow UI
│  └─ Read time-profiler.md
│
├─ Scroll or animation stutter / dropped frames / hitches
│  └─ Read hitches.md
│
├─ High memory / leaks / OOM crashes / growing footprint
│  └─ Read memory-profiling.md
│
├─ Slow app launch / time to first frame
│  └─ Read launch-optimization.md
│
├─ Battery drain / thermal throttling / background energy
│  └─ Read energy-diagnostics.md
│
├─ General "app feels slow" (unknown cause)
│  └─ Start with time-profiler.md, then memory-profiling.md
│
└─ Pre-release performance audit
   └─ Read ALL reference files, use Review Checklist below

クイックリファレンス

問題インストゥルメント/ツール主な指標リファレンス
UI のハングが 250ms を超えるTime Profiler + Hangsハング時間、メインスレッドのスタックtime-profiler.md
スクロール/アニメーションのカクつきAnimation Hitches テンプレートカクつき時間の割合(< 5 ms/s は良好、> 10 は重大)hitches.md
高い CPU 使用率Time Profiler / CPU Profiler関数ごとの CPU %、コールツリーの重みtime-profiler.md
メモリリークLeaks + Memory Graphリークしたバイト数、リテインサイクルのパスmemory-profiling.md
メモリの増加Allocations生存バイト数、世代分析memory-profiling.md
起動が遅いApp Launch最初のフレームまでの時間(pre-main + post-main)launch-optimization.md
バッテリー消費Energy Log / Power ProfilerEnergy Impact スコア、CPU/GPU/ネットワークenergy-diagnostics.md
熱の問題Activity Monitorサーマル状態の遷移energy-diagnostics.md
ネットワークの無駄Network profiler重複したフェッチ、大きなペイロードenergy-diagnostics.md

主要な 8 つの指標(WWDC21 10181)

Apple は、アプリのパフォーマンスで追跡すべき項目を正確に 8 つ挙げています。これらは 5 つのツール(Xcode Organizer、MetricKit、Instruments、XCTest、App Store Connect API)ですべて確認できます。

#指標しきい値/シグナルツール
1バッテリー使用量Energy Gauge は、CPU 使用率が 20% 超の場合に High CPU としてフラグを付け、CPU Wake Overhead の領域も示します。確認すべき主なサブシステムは CPU、ネットワーク、位置情報ですEnergy Gauge → Time Profiler
2起動時間アイコンをタップしてから最初のフレームが描画されるまでの時間App Launch テンプレート、XCTApplicationLaunchMetric
3ハング率250ms 以上入力に応答しない状態Hangs インストゥルメント、Organizer
4メモリOrganizer はピークメモリとサスペンド時のメモリをグラフに表示します。終了のスパイクがまだ発生していない段階でのスパイクは、早期警告ですAllocations、Leaks、VM Tracker
5ディスク書き込みアプリが24 時間で 1 GB 超を書き込むと例外レポートが生成されます(スタックトレースと Insights の注釈を含む)File Activity テンプレート、XCTStorageMetric
6スクロールOrganizer のスクロールグラフに赤いバーが表示されている場合、スクロール体験が良くありません。すぐに修正してくださいAnimation Hitches、XCTOSSignpostMetric.scrollDecelerationMetric
7終了終了するたびに次回は遅いコールド起動が必要になり、ユーザーの状態も失われますMXAppExitMetric、Organizer
8MXSignposts重要なコードセクションをカスタムマークした区間MetricKit

Organizer は、同意したユーザーのデバイスから、これらすべてのデータを直近 16 バージョンにわたって集計します。Regressions ペイン(Xcode 13)では、最新バージョンで大幅に増加した指標をすべて一か所で確認できます。同じデータは App Store Connect API を介して JSON 形式でも利用できます(WWDC21 10181)。

手順

1. 問題のカテゴリを特定する

ユーザーに尋ねるか、説明を確認して、問題を分類します。

  • 応答性:ハング、カクつき、アニメーションのフレーム落ち
  • メモリ:リーク、増加、OOM クラッシュ
  • 起動:コールド/ウォーム起動が遅い
  • エネルギー:バッテリー消費、熱によるスロットリング
2. 適切なリファレンスファイルを読む

各ファイルには次の内容が含まれています。

  • 使用する Instruments テンプレート
  • プロファイリングの手順
  • 結果の解釈方法
  • コード例を含む一般的な修正パターン
3. 実機でプロファイリングする

必ずユーザーに次の点を伝えてください。

  • シミュレータではなく実機でプロファイリングする(シミュレータはホストの CPU/メモリを使用します)
  • Release ビルド構成を使用する(最適化によって動作が変わります)
  • 実際の利用状況を反映したデータでプロファイリングする(データベースが空だと、実際のパフォーマンスの問題が見えません)
  • ノイズを減らすため、ほかのアプリを終了する
4. 修正を適用して検証する

ボトルネックを特定したら、次の手順を行います。

  • リファレンスファイルの対象を絞った修正を適用する
  • 再度プロファイリングして改善を確認する
  • 継続的な監視のために os_signpost マーカーを追加する

Xcode の診断設定

Scheme > Run > Diagnostics で次の設定を有効にすることを推奨します。

設定検出できる問題
Main Thread Checkerメインスレッド以外での UI 処理
Thread Sanitizerデータ競合
Address Sanitizerバッファーオーバーフロー、解放後使用
Malloc Stack Loggingメモリ割り当てのコールスタック
Zombie Objects解放済みオブジェクトへのメッセージ送信

MetricKit の統合

本番環境での監視には、MetricKit の使用を推奨します(WWDC20 10081、WWDC21 10181)。

import MetricKit

final class PerformanceReporter: NSObject, MXMetricManagerSubscriber {
    func startCollecting() {
        MXMetricManager.shared.add(self)   // subscribe once, early in launch
    }
    // best practice: remove(self) in deinit (WWDC21 10181)

    func didReceive(_ payloads: [MXMetricPayload]) {
        for payload in payloads {
            // Launch time
            if let launch = payload.applicationLaunchMetrics {
                log("Resume time: \(launch.histogrammedResumeTime)")
            }
            // Hang rate
            if let responsiveness = payload.applicationResponsivenessMetrics {
                log("Hang time: \(responsiveness.histogrammedApplicationHangTime)")
            }
            // Memory
            if let memory = payload.memoryMetrics {
                log("Peak memory: \(memory.peakMemoryUsage)")
            }
            // Scroll hitches (ratio of time hitching to time scrolling)
            if let animation = payload.animationMetrics {
                log("Scroll hitch ratio: \(animation.scrollHitchTimeRatio)")
            }
            // Exit reasons — daily counts per termination cause, fg + bg
            if let exits = payload.applicationExitMetrics {
                log("Exits: \(exits.backgroundExitData)")
            }
        }
    }

    func didReceive(_ payloads: [MXDiagnosticPayload]) {
        for payload in payloads {
            if let hangs = payload.hangDiagnostics {
                for hang in hangs {
                    log("Hang: \(hang.callStackTree)")
                }
            }
        }
    }
}

主な情報(WWDC20 10081、WWDC21 10181):

  • ❌ サブスクリプションを遅延させると(例:設定画面で登録する)、配信されたペイロードを気付かないまま取りこぼします。✅ App/AppDelegate の init でサブスクライブしてください。前日のペイロードはアプリの起動時に渡されます。
  • メトリクスは 24 時間分のペイロードとして、1 日に最大 1 回、累積、平均、バケット化(MXHistogram)の 3 つの集計形式で届きます。iOS 15+/macOS 12+ では、すべての診断情報が日次ではなく、問題の発生直後に配信されます。
  • 終了情報とメモリのテレメトリは、デフォルトで日次のメトリクスペイロードに含まれます。追加の計測は不要です。
  • 診断の種類:MXHangDiagnostic(メインスレッドの応答停止時間とバックトレース)、MXCrashDiagnostic(例外情報、終了理由、VM 領域情報)、MXCPUExceptionDiagnostic(CPU を消費しているスレッド。Organizer のエネルギーログに相当するプログラム上の情報)、MXDiskWriteExceptionDiagnostic(1 GB/日の書き込みしきい値を超えたときに発生)。
  • MXCallStackTree のバックトレースは設計上、シンボル化されていません。atos クラスのツールと dSYM を使ってデバイス外でシンボル化してください。❌ デバイス上で行おうとしないでください。
  • MXSignpost は、フィールドテレメトリ用に重要なコードセクションをマークします。アニメーション用のバリアントは、その区間のヒッチ率テレメトリを取得します。
let handle = MXMetricManager.makeLogHandle(category: "animation_telemetry")
mxSignpostAnimationIntervalBegin(log: handle, name: "custom_animation")
// ... animation ...
mxSignpost(OSSignpostType.end, log: handle, name: "custom_animation")

レビューチェックリスト

応答性
  • メインスレッドで 100 ms を超える同期処理がない
  • メインスレッドでファイル I/O やネットワーク呼び出しを行っていない
  • 大規模なクエリでは、Core Data/SwiftData のフェッチにバックグラウンドコンテキストを使用している
  • 画像をメインスレッド以外でデコードしている(.preparingThumbnail または非同期デコードを使用)
  • @MainActor は、UI へのアクセスが本当に必要なコードにのみ使用している
メモリ
  • 保持サイクルがない(デリゲートパターンや、self を使用するクロージャを確認)
  • 表示されていない大きなリソースを解放している(画像、キャッシュ)
  • コレクションが無制限に増加しない(上限付きキャッシュ、ページネーション)
  • ObjC オブジェクトを生成するタイトなループで autoreleasepool を使用している
起動時間
  • @main App 構造体の init() で重い処理を行っていない
  • 必須ではない初期化(分析、先読み)を後回しにしている
  • 動的フレームワークを最小限にしている(静的リンクを優先)
  • 起動時に同期ネットワーク呼び出しを行っていない
エネルギー
  • バックグラウンドタスクで BGProcessingTaskRequest を適切に使用している
  • 位置情報の精度が実際の必要性に合っている(常に .best にしていない)
  • タイマーで tolerance を設定し、実行のまとめ合わせを可能にしている
  • 可能な場合はネットワークリクエストをまとめている

参考資料

コメント