performance-profiling について
Appleプラットフォームのアプリ開発者向けパフォーマンス分析ガイドです。Instruments、Xcode診断、MetricKitを使い、応答性・メモリ・起動時間・エネルギーの調査手順と修正パターンを扱います。
主な機能
- 01CPU・メモリ・起動・電力の分析
- 02問題に応じた分析ツールの選択
- 03分析手順と修正パターンの提示
- 04MetricKitによる本番環境の監視
- 05チェックリストによる性能確認
活用シーン
- 01UIのハングやフレーム落ちの調査
- 02メモリリークや増加の特定
- 03アプリ起動時間の最適化
- 04電池消費や熱問題の診断
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ rshankras/ claude-code-apple-skills --skill performance-profilingインストール後、Claude Code で/performance-profilingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
energy-diagnostics.mdhitches.mdlaunch-optimization.mdmemory-profiling.mdtime-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 Profiler | Energy 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 |
| 8 | MXSignposts | 重要なコードセクションをカスタムマークした区間 | 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を設定し、実行のまとめ合わせを可能にしている - 可能な場合はネットワークリクエストをまとめている
参考資料
- time-profiler.md — CPU プロファイリング、ハング検出の手順、signpost API、Instruments の 27 種類のツール
- hitches.md — レンダーループ、ハッチ時間比、コミット/レンダーフェーズの修正カタログ
- memory-profiling.md — Allocations、Leaks、メモリーグラフデバッガー、memgraph CLI、終了理由
- launch-optimization.md — アプリの起動フェーズ、コールド/ウォームスタートの最適化、リンカーの調整項目
- energy-diagnostics.md — バッテリー、熱状態、ネットワーク効率、Power Profiler
- WWDC:アプリケーションのパフォーマンスを守り抜くための究極ガイド
- WWDC:アプリのハングを理解して解消する
- WWDC:Xcode とデバイス上の検出機能でハングを特定する
- WWDC:Instruments でハングを分析する
- WWDC:メモリーの問題を検出して診断する
- WWDC:ヒープメモリーを分析する
- WWDC:アプリが強制終了される理由
- WWDC:MetricKit の新機能
- WWDC:アプリの起動を最適化する
- WWDC:Instruments で CPU パフォーマンスを最適化する
- WWDC:アプリの電力使用量をプロファイリングして最適化する
- WWDC:プロファイリング、修正、検証 — Instruments でアプリの応答性を高める