axiom-energy-diag について
iOSとiPadOSの開発者向けに、症状別のエネルギー診断を行うスキルです。バッテリー消費、端末の発熱、バックグラウンド消費などの判断フローと修正案を示し、Power Profilerなどで原因を特定する方法を扱います。
主な機能
- 01症状別のエネルギー診断
- 02段階的な判断フロー
- 03Power Profilerによる原因特定
- 04よくある消費パターンと修正案
- 05簡易診断チェックリスト
活用シーン
- 01設定画面で高いバッテリー消費を調査
- 02端末が発熱する原因を特定
- 03バックグラウンド消費を診断
- 04セルラー通信時の消費増加を調査
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ charleswiltgen/ axiom --skill axiom-energy-diagインストール後、Claude Code で/axiom-energy-diagを入力して読み込まれたか確認します。
詳細
エネルギー診断
エネルギー関連の問題を症状に基づいてトラブルシューティングします。症状から始めて、判断ツリーに従い、解決策を確認してください。
関連スキル:axiom-energy(パターン、チェックリスト)、axiom-energy-ref(API リファレンス)
症状 1:バッテリー設定でアプリが上位に表示される
ユーザー、またはあなた自身が、アプリのバッテリー消費量がかなり多いことに気づきました。
診断の判断ツリー
App at top of Battery Settings?
│
├─ Step 1: Run Power Profiler (15 min)
│ ├─ CPU Power Impact high?
│ │ ├─ Continuous? → Timer leak or polling loop
│ │ │ └─ Fix: Check timers, add tolerance, convert to push
│ │ └─ Spikes during actions? → Eager loading or repeated parsing
│ │ └─ Fix: Use LazyVStack, cache parsed data
│ │
│ ├─ Network Power Impact high?
│ │ ├─ Many small requests? → Batching issue
│ │ │ └─ Fix: Batch requests, use discretionary URLSession
│ │ └─ Regular intervals? → Polling pattern
│ │ └─ Fix: Convert to push notifications
│ │
│ ├─ GPU Power Impact high?
│ │ ├─ Animations? → Running when not visible
│ │ │ └─ Fix: Stop in viewWillDisappear
│ │ └─ Blur effects? → Over dynamic content
│ │ └─ Fix: Remove or use static backgrounds
│ │
│ └─ Display Power Impact high?
│ └─ Light backgrounds on OLED?
│ └─ Fix: Implement Dark Mode (up to 70% savings)
│
└─ Step 2: Check background section in Battery Settings
├─ High background time?
│ ├─ Location icon visible? → Continuous location
│ │ └─ Fix: Switch to significant-change monitoring
│ ├─ Audio active? → Session not deactivated
│ │ └─ Fix: Deactivate audio session when not playing
│ └─ BGTasks running long? → Not completing promptly
│ └─ Fix: Call setTaskCompleted sooner
│
└─ Background time appropriate?
└─ Issue is in foreground usage → Focus on CPU/GPU fixes above
時間とコストの分析
| 方法 | 時間 | 精度 |
|---|---|---|
| Power Profiler を実行して、サブシステムを特定する | 15-20 分 | 高 |
| 推測して無作為に最適化する | 4 時間以上 | 低 |
| 問題を探してすべてのコードを読む | 2 時間以上 | 中 |
推奨事項:必ず最初に Power Profiler を使用してください。15 分かかりますが、最適化すべきサブシステムを確実に特定できます。
症状 2:デバイスが熱くなる
アプリの使用中に、デバイスの温度が目に見えて上昇します。
診断の判断ツリー
Device gets hot during app use?
│
├─ Hot during specific action?
│ │
│ ├─ During video/camera use?
│ │ ├─ Video encoding? → Expected, but check efficiency
│ │ │ └─ Fix: Use hardware encoding, reduce resolution if possible
│ │ └─ Camera active unnecessarily? → Not releasing session
│ │ └─ Fix: Call stopRunning() when done
│ │
│ ├─ During scroll/animation?
│ │ ├─ GPU-intensive effects? → Blur, shadows, many layers
│ │ │ └─ Fix: Reduce effects, cache rendered content
│ │ └─ High frame rate? → Unnecessary 120fps
│ │ └─ Fix: Use CADisplayLink preferredFrameRateRange
│ │
│ └─ During data processing?
│ ├─ JSON parsing? → Repeated or large payloads
│ │ └─ Fix: Cache parsed results, paginate
│ └─ Image processing? → Synchronous on main thread
│ └─ Fix: Move to background, cache results
│
├─ Hot during normal use (no specific action)?
│ │
│ ├─ Run Power Profiler to identify:
│ │ ├─ CPU high continuously → Timer, polling, tight loop
│ │ ├─ GPU high continuously → Animation leak
│ │ └─ Network high continuously → Polling pattern
│ │
│ └─ Check for infinite loops or runaway recursion
│ └─ Use Time Profiler in Instruments
│
└─ Hot only in background?
├─ Location updates continuous? → High accuracy or no stop
│ └─ Fix: Reduce accuracy, stop when done
├─ Audio session active? → Hardware kept powered
│ └─ Fix: Deactivate when not playing
└─ BGTask running too long? → System may throttle
└─ Fix: Complete tasks faster, use requiresExternalPower
時間とコストの分析
| 方法 | 時間 | 結果 |
|---|---|---|
| Power Profiler と Time Profiler | 20-30 分 | 正確な原因を特定 |
| 明らかな問題がないかコードを確認する | 1-2 時間 | 明白でない原因を見逃す可能性がある |
| ユーザーからの苦情を待つ | 該当なし | 評判が損なわれる |
症状 3:バックグラウンドでのバッテリー消耗
ユーザーがアプリを積極的に使用していないときも、バッテリーが消耗します。
診断の判断ツリー
High background battery usage?
│
├─ Step 1: Check Info.plist background modes
│ │
│ ├─ "location" enabled?
│ │ ├─ Actually need background location?
│ │ │ ├─ YES → Use significant-change, lowest accuracy
│ │ │ └─ NO → Remove background mode, use when-in-use only
│ │ └─ Check: Is stopUpdatingLocation called?
│ │
│ ├─ "audio" enabled?
│ │ ├─ Audio playing? → Expected
│ │ ├─ Audio NOT playing? → Session still active
│ │ │ └─ Fix: Deactivate session, use autoShutdownEnabled
│ │ └─ Playing silent audio? → Anti-pattern for keeping app alive
│ │ └─ Fix: Use proper background API (BGTask)
│ │
│ ├─ "fetch" enabled?
│ │ └─ Check: Is earliestBeginDate reasonable? (not too frequent)
│ │
│ └─ "remote-notification" enabled?
│ └─ Expected for push updates, check didReceiveRemoteNotification efficiency
│
├─ Step 2: Check BGTaskScheduler usage
│ │
│ ├─ BGAppRefreshTask scheduled too frequently?
│ │ └─ Fix: Increase earliestBeginDate interval
│ │
│ ├─ BGProcessingTask not using requiresExternalPower?
│ │ └─ Fix: Add requiresExternalPower = true for non-urgent work
│ │
│ └─ Tasks not completing? (setTaskCompleted not called)
│ └─ Fix: Always call setTaskCompleted, implement expirationHandler
│
└─ Step 3: Check beginBackgroundTask usage
│
├─ endBackgroundTask called promptly?
│ └─ Fix: Call immediately after work completes, not at expiration
│
└─ Multiple overlapping background tasks?
└─ Fix: Track task IDs, ensure each is ended
バックグラウンドでよくあるバッテリー消耗パターン
| パターン | Power Profiler のシグネチャ | 修正方法 |
|---|---|---|
| 位置情報を継続的に取得 | CPU レーン + 位置情報アイコン | significant-change |
| オーディオセッションのリーク | CPU レーンが一定 | setActive(false) |
| タイマーが無効化されていない | 一定間隔で CPU が急上昇 | バックグラウンドで無効化 |
| バックグラウンドからのポーリング | 一定間隔で Network レーンに表示 | プッシュ通知 |
| BGTask の実行時間が長すぎる | CPU の高負荷が持続 | より速く完了させる |
時間とコストの分析
| 方法 | 時間 | 結果 |
|---|---|---|
| Info.plist と BGTask のコードを確認する | 30 分 | よくある問題を発見 |
| デバイス上で Power Profiler のトレースを取得する | 1-2 時間(実使用時) | 実際の動作を記録 |
| ユーザーが収集したトレース | 可変 | 再現できない問題に最適 |
症状 4:セルラー通信時のみエネルギー消費が大きい
WiFi よりもセルラー通信時のほうが、バッテリーの減りが速くなります。
診断の判断ツリー
High battery drain on cellular only?
│
├─ Expected: Cellular radio uses more power than WiFi
│ └─ But: Excessive drain indicates optimization opportunity
│
├─ Check URLSession configuration
│ │
│ ├─ allowsExpensiveNetworkAccess = true (default)?
│ │ └─ Fix: Set to false for non-urgent requests
│ │
│ ├─ isDiscretionary = false (default)?
│ │ └─ Fix: Set to true for background downloads
│ │
│ └─ waitsForConnectivity = false (default)?
│ └─ Fix: Set to true to avoid failed connection retries
│
├─ Check request patterns
│ │
│ ├─ Many small requests? → High connection overhead
│ │ └─ Fix: Batch into fewer larger requests
│ │
│ ├─ Polling? → Radio stays active
│ │ └─ Fix: Push notifications
│ │
│ └─ Large downloads in foreground? → Could wait for WiFi
│ └─ Fix: Use background URLSession with discretionary
│
└─ Check Low Data Mode handling
├─ Respecting allowsConstrainedNetworkAccess?
│ └─ Fix: Set to false for non-essential requests
│
└─ Checking ProcessInfo.processInfo.isLowDataModeEnabled?
└─ Fix: Reduce payload sizes, defer non-essential transfers
時間とコストの分析
| 方法 | 時間 | 結果 |
|---|---|---|
| URLSession の設定を確認する | 15 分 | すぐに効果が出る改善 |
| discretionary フラグを追加する | 30 分 | 大幅な節約 |
| ポーリングをプッシュに切り替える | 2-4 時間 | 最大の効果 |
症状 5:特定の操作中にエネルギー消費が急増する
特定の操作を実行すると、バッテリー消耗や発熱が目立ちます。
診断の判断ツリー
Energy spike during specific action?
│
├─ Step 1: Record Power Profiler during action
│ └─ Note which subsystem spikes (CPU/GPU/Network/Display)
│
├─ CPU spike?
│ │
│ ├─ Is it parsing data?
│ │ ├─ Same data parsed repeatedly?
│ │ │ └─ Fix: Cache parsed results (lazy var)
│ │ └─ Large JSON/XML payload?
│ │ └─ Fix: Paginate, stream parse, or use binary format
│ │
│ ├─ Is it creating views?
│ │ ├─ Many views at once?
│ │ │ └─ Fix: Use LazyVStack/LazyHStack
│ │ └─ Complex view hierarchies?
│ │ └─ Fix: Simplify, use drawingGroup()
│ │
│ └─ Is it image processing?
│ ├─ On main thread?
│ │ └─ Fix: Move to background queue
│ └─ No caching?
│ └─ Fix: Cache processed images
│
├─ GPU spike?
│ │
│ ├─ Starting animation?
│ │ └─ Fix: Ensure frame rate appropriate
│ │
│ ├─ Showing blur effect?
│ │ └─ Fix: Use solid color or pre-rendered blur
│ │
│ └─ Complex render? (shadows, masks, many layers)
│ └─ Fix: Simplify, use shouldRasterize, cache
│
├─ Network spike?
│ │
│ ├─ Large download started?
│ │ └─ Fix: Use background URLSession, show progress
│ │
│ ├─ Many parallel requests?
│ │ └─ Fix: Limit concurrency, batch
│ │
│ └─ Retrying failed requests?
│ └─ Fix: Exponential backoff, waitsForConnectivity
│
└─ Display spike?
└─ Unusual unless changing brightness programmatically
└─ Fix: Don't modify brightness, let system control
時間とコストの分析
| 方法 | 時間 | 結果 |
|---|---|---|
| 操作中に Power Profiler を実行する | 5-10 分 | サブシステムを特定 |
| Time Profiler で CPU の詳細を確認する | 10-15 分 | 関数を特定 |
| プロファイリングせずにコードレビューする | 1 時間以上 | 実際の原因を見逃す可能性がある |
簡易診断チェックリスト
すばやく答えを見つける必要がある場合に使用してください。
30 秒チェック
- デバイスが電源に接続されていますか?(電力の測定値が 0 になります)
- デバッグビルドですか?(リリースビルドより最適化されていません)
- 低電力モードがオンですか?(測定結果に影響する場合があります)
5 分チェック(Power Profiler)
- どのサブシステムが支配的ですか?(CPU/GPU/Network/Display)
- 負荷は持続していますか、それとも急増していますか?
- フォアグラウンドですか、バックグラウンドですか?
15 分の調査
- CPU の場合:Time Profiler を実行して関数を特定する
- Network の場合:リクエストの頻度とサイズを確認する
- GPU の場合:アニメーションのフレームレートを確認する
- バックグラウンドの場合:Info.plist のモードを確認する
よくある簡単な修正
| 検出項目 | 簡単な修正 | 所要時間 |
|---|---|---|
| 許容範囲を指定していないタイマー | .tolerance = 0.1 を追加します | 1 min |
| 要素数の多い ForEach を含む VStack | LazyVStack に変更します | 1 min |
| allowsExpensiveNetworkAccess = true | false に設定します | 1 min |
| stopUpdatingLocation がない | stop 呼び出しを追加します | 2 min |
| ダークモードに未対応 | アセットのバリエーションを追加します | 30 min |
| オーディオセッションが常にアクティブ | setActive(false) を追加します | 5 min |
エスカレーションする場合
次のような場合は axiom-energy スキルを使用します
- 完全な監査チェックリストが必要な場合
- コード付きの包括的なパターンを確認したい場合
- 予防的な最適化を計画している場合
次のような場合は axiom-energy-ref スキルを使用します
- 特定の API の詳細が必要な場合
- 完全なコード例を確認したい場合
- ゼロから実装する場合
次のような場合は energy-auditor エージェントを使用します
- コードベースを自動スキャンしたい場合
- 大規模なアンチパターンを探している場合
- リリース前にエネルギー監査を行う場合
実行:/axiom:audit energy
最終更新日:2025-12-26 プラットフォーム:iOS 26+、iPadOS 26+
コメント
Markdown 対応