ワンクリックで
instruments-profiler
xctrace CLIでiOS/macOSアプリをInstrumentsプロファイリングし、パフォーマンス問題を特定・修正するワークフロー。「Instrumentsで計測」「プロファイリング」「パフォーマンス計測」で使用。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
xctrace CLIでiOS/macOSアプリをInstrumentsプロファイリングし、パフォーマンス問題を特定・修正するワークフロー。「Instrumentsで計測」「プロファイリング」「パフォーマンス計測」で使用。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
| name | instruments-profiler |
| description | xctrace CLIでiOS/macOSアプリをInstrumentsプロファイリングし、パフォーマンス問題を特定・修正するワークフロー。「Instrumentsで計測」「プロファイリング」「パフォーマンス計測」で使用。 |
xctrace CLIを使ってiOS/macOSアプリをInstrumentsでプロファイリングし、パフォーマンス問題を特定・修正する。
デバイス一覧を取得
# シミュレータ一覧
xcrun simctl list devices available
# 実機 + シミュレータ一覧(xctrace用UDID付き)
xctrace list devices
具体的なデバイスをユーザーに確認(AskUserQuestionを使用)
シミュレータと実機の両方を選択肢に含める:
questions: [{
question: "プロファイリングを実行するデバイスを選択してください(実機推奨)",
header: "デバイス",
options: [
{ label: "<実機名1>", description: "実機 - UDID: xxx(推奨)" },
{ label: "<実機名2>", description: "実機 - UDID: yyy(推奨)" },
{ label: "iPhone 17 Pro (Simulator)", description: "シミュレータ" }
],
multiSelect: false
}]
ポイント: 実機を先頭に表示し推奨する。実機の方がシミュレータより安定した動作が期待できる。
デバイスUDIDの取得
xctrace list devicesの出力からUDIDを取得する:
例: John's iPhone (26.0) (00008101-XXXXXXXXXXXX) → UDIDは 00008101-XXXXXXXXXXXX
重要: Debugビルドは最適化なしで計測不正確。必ずReleaseビルドを使用。
シミュレータの場合:
xcodebuild -scheme "<スキーム名>" \
-configuration Release \
-destination "id=<シミュレータUDID>" \
-derivedDataPath /tmp/DerivedData \
build
# appパスを取得
APP_PATH=$(find /tmp/DerivedData -name "*.app" -path "*/Release-iphonesimulator/*" | head -1)
# シミュレータにインストール
xcrun simctl install "<シミュレータUDID>" "$APP_PATH"
実機の場合:
xcodebuild -scheme "<スキーム名>" \
-configuration Release \
-destination "id=<実機UDID>" \
-derivedDataPath /tmp/DerivedData \
build
# appパスを取得
APP_PATH=$(find /tmp/DerivedData -name "*.app" -path "*/Release-iphoneos/*" | head -1)
# 実機にインストール
xcrun devicectl device install app --device "<実機UDID>" "$APP_PATH"
bundleIdの取得:
defaults read "$APP_PATH/Info.plist" CFBundleIdentifier
ユーザーに計測モードを確認(AskUserQuestionを使用):
questions: [{
question: "計測モードを選択してください(Leaks, Allocations, Animation Hitches, Energy Logはその他から入力)",
header: "計測モード",
options: [
{ label: "SwiftUI", description: "Time Profiler + View Body + Hangs + Hitches" },
{ label: "App Launch", description: "起動時間 + フェーズ分析" },
{ label: "Time Profiler", description: "CPU時間プロファイリング(汎用)" }
],
multiSelect: false
}]
注意:
トレースファイル名の生成(ファイル名衝突を防ぐためタイムスタンプを使用):
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
TRACE_FILE="/tmp/profile_${TIMESTAMP}.trace"
TRACE_SYM_FILE="/tmp/profile_${TIMESTAMP}_sym.trace"
EXPORT_DIR="/tmp/exported_${TIMESTAMP}"
App Launchは起動完了を自動検出して終了するため、確認なしで直接実行する。
# 同期実行(自動終了を待つ)
xctrace record \
--template "App Launch" \
--device "<デバイス>" \
--output $TRACE_FILE \
--launch <bundleId>
起動方法の選択(AskUserQuestionを使用):
questions: [{
question: "アプリの起動方法を選択してください",
header: "起動方法",
options: [
{ label: "起動中のアプリに接続", description: "既に起動中のアプリにアタッチ(--attach)" },
{ label: "アプリを起動して計測", description: "アプリを新規起動してプロファイリング(--launch)" }
],
multiSelect: false
}]
「起動中のアプリに接続」を選択した場合:
# PIDを検索
ps aux | grep <アプリ名>
# または xcrun devicectl で実機のプロセス一覧を取得
実行フロー:
run_in_background: trueでxctraceを実行(--time-limitなし)# バックグラウンドで実行(time-limitなし)
Bash(run_in_background: true):
# --attach の場合
xctrace record --template "SwiftUI" --device "<デバイス>" --output $TRACE_FILE --attach <PID>
# --launch の場合
xctrace record --template "SwiftUI" --device "<デバイス>" --output $TRACE_FILE --launch <bundleId>
# → shell_idを控える
# ユーザーに停止タイミングを確認
AskUserQuestion:
question: "アプリを操作してください。計測を終了する場合は停止を押してください"
options: [
{ label: "停止", description: "計測を終了して解析を開始" },
{ label: "停止", description: "計測を終了して解析を開始" }
]
# 「停止」が選択されたら
pkill -INT -f "xctrace record"
# TaskOutputで完了を確認
TaskOutput(task_id: "<shell_id>", block: false)
汎用CPUプロファイリング。SwiftUIテンプレートと同様のフローを使用。
メモリ関連テンプレートはユーザー操作が必要で、SwiftUIテンプレートと同様のフローを使用。
注意: Leaks/Allocationsは十分なメモリ操作(画面遷移、データ読み込み等)を行ってから停止すること。
フレームドロップ検出。スクロールやアニメーション操作が必要。SwiftUIテンプレートと同様のフローを使用。
重要: Energy Logは実機のみで正確なデータが取得可能。シミュレータでは意味のあるデータが得られない。
デバイス選択時にシミュレータが選択された場合は警告を表示し、実機を選択するよう促す。
--attach(起動中のアプリに接続):
xctrace record --template "<テンプレート>" --device "<デバイス名 or UDID>" --output $TRACE_FILE --attach <PID>
--launch(アプリを起動して計測):
xctrace record --template "<テンプレート>" --device "<デバイス名 or UDID>" --output $TRACE_FILE --launch <bundleId>
注意:
--launchや--attach引数はコマンドの最後に配置アプリコードのシンボルを解決するために、dSYMを使ってトレースをシンボル化:
xctrace symbolicate \
--input $TRACE_FILE \
--output $TRACE_SYM_FILE \
--dsym ~/Library/Developer/Xcode/DerivedData/<project>/Build/Products/Release-iphoneos/
シンボル化しないと: アプリのコードがunknownや<deduplicated_symbol>として表示される。
<skill_dir>/scripts/export_trace.sh $TRACE_SYM_FILE $EXPORT_DIR
出力:
$EXPORT_DIR/toc.xml - テーブル一覧$EXPORT_DIR/time-profile.xml - Time Profilerデータ$EXPORT_DIR/report.md - 解析レポート# 基本的な解析
<skill_dir>/scripts/parse_trace.py $EXPORT_DIR
# アプリ固有コードをフィルタリング
<skill_dir>/scripts/parse_trace.py $EXPORT_DIR --app "MyApp"
# Flame Graph用データのみ出力
<skill_dir>/scripts/parse_trace.py $EXPORT_DIR --collapsed-only
出力内容:
解析観点:
| パターン | 意味 | 対処 |
|---|---|---|
| Self Time高 | その関数自体が重い | アルゴリズム改善、キャッシュ |
| Total Time高 / Self Time低 | 呼び出し先に問題 | 呼び出し先を調査 |
| SwiftUI関連が多い | View更新が頻繁 | 状態スコープ縮小 |
重要: 報告のフィルタリング
解析結果を表示した後、ユーザーに改善計画を立てるかどうかを確認する(AskUserQuestionを使用):
questions: [{
question: "解析が完了しました。改善計画を立てますか?",
header: "次のステップ",
options: [
{ label: "改善計画を立てる", description: "問題箇所を特定し、具体的な修正プランを作成" },
{ label: "結果の確認のみ", description: "今回は計測結果の確認だけで終了" }
],
multiSelect: false
}]
「改善計画を立てる」を選択した場合:
EnterPlanMode で詳細な実装計画を作成「結果の確認のみ」を選択した場合:
/instruments-profiler で再度計測可能であることを伝えるgit clone https://github.com/brendangregg/FlameGraph
./FlameGraph/flamegraph.pl $EXPORT_DIR/collapsed.txt > flamegraph.svg
注意: パフォーマンスに実質的な影響がある問題のみ提案する。無視できるレベルの小さな問題には言及しない。
問題特定後、以下のパターンを適用:
| 問題 | 解決策 |
|---|---|
| ループ内のData.append | withUnsafeMutableBytesで直接書き込み |
| Array.removeFirst (O(n)) | リングバッファまたはインデックス管理 |
| View invalidation storms | 状態スコープの縮小 |
| Heavy work in body | 事前計算・キャッシュ |
| Large images | ダウンサンプリング |
| エラー | 原因 | 対処 |
|---|---|---|
| Permission denied | 開発者ツールアクセス未許可 | システム設定で許可 |
| Device not found | デバイス名/UDIDが不正 | xctrace list devicesで確認 |
| Template not found | テンプレート名が不正 | xctrace list templatesで確認 |
| Empty trace | 操作なし/すぐ停止した | 十分にアプリを操作してから停止 |
| シンボルがunknown | dSYMがない | xctrace symbolicateでシンボル化 |
| Cannot find process | プロセス検索失敗 | --launchオプションを使用 |
| Leaks/Allocationsが空 | track-based exportが必要 | export_trace.shが最新か確認 |
| Energy Logデータなし | シミュレータ非対応 | 実機で計測(シミュレータでは取得不可) |
| No energy data | Xcode 13以前の制限 | Xcode 13以降にアップデート |
references/xctrace-commands.mdreferences/output-format.mdreferences/workflow-examples.md