swiftui-performance について
swiftui-performanceは、変更によるビューの無効化と更新に着目してSwiftUIコードをレビュー、リファクタリングするスキルです。ID、状態、依存関係、レイアウト、ライフサイクルを調べ、描画処理の影響範囲を抑える方法を提案します。
主な機能
- 01ビューIDと状態の所有関係を分析
- 02body内の高コスト処理を検出
- 03広範なモデル依存を確認
- 04リスト・レイアウト・描画コストをレビュー
- 05非同期処理のライフサイクルとキャンセルを評価
- 06的を絞ったリファクタリングと検証を提案
活用シーン
- 01SwiftUI画面やリストのレビュー
- 02不要なビュー更新の削減
- 03スクロールやアニメーションの引っかかり調査
- 04SwiftUI性能仮説の検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ livsy90/ ios-performance-agent-skills --skill swiftui-performanceインストール後、Claude Code で/swiftui-performanceを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamlreferences/async-lifecycle-and-mainactor.mdbody-cost-and-render-models.mdclosures-bindings-and-equatable.mdidentity-and-state.mdlayout-drawing-and-animation.mdlists-pagination-and-rows.mdobservation-and-dependencies.mdprofiling-validation.md詳細
SwiftUI のパフォーマンス
目的
パフォーマンスを最優先し、変更の局所性に焦点を当てた考え方で、SwiftUI コードをレビューおよびリファクタリングする際にこのスキルを使用します。
SwiftUI のパフォーマンス改善では、どの変更が UI のどの部分を無効化するのか、その処理がなぜ重要なのか、更新を局所化する方法を説明する必要があります。
対象範囲
このスキルは、次の場合に使用します。
- SwiftUI の画面、リスト、行、レイアウト、描画、アニメーション、ライフサイクルのレビュー
- 不要な更新や描画処理を減らすための、対象を絞ったリファクタリング
- SwiftUI のパフォーマンスに関する仮説を検証する場合に限った、プロファイリング計画
次の場合にはこのスキルを使用しないでください。
- UIKit のみで発生するパフォーマンスの問題
- SwiftUI のルートビューやシーンの構築に問題が含まれている場合を除く、アプリの起動パフォーマンス
- SwiftUI の更新に影響する場合を除く、ネットワーク、バックエンドのレイテンシ、データベースのパフォーマンス、キャッシュ
- SwiftUI のコードパスを伴わない、一般的な Instruments の使い方の説明
- SwiftUI の具体的なパフォーマンスリスクを伴わない、広範なアーキテクチャの書き換え
基本モデル
まず、次の3つの問いに答えます。
- 何が変わりましたか?
- その変更に依存しているビューはどれですか?
- その変更によって、どれほどの UI 処理が発生しますか?
次に、以下を確認します。
- アイデンティティ:更新をまたいで、SwiftUI は同じ論理的なビューを維持していますか?
- ライフタイム:状態は、それを必要とする最小の安定したコンポーネントが所有していますか?
- 依存関係:各ビューは、描画に必要なデータだけを読み取っていますか?
- 描画:
bodyは軽量で予測可能であり、重い変換処理を含んでいませんか? - ライフサイクル:非同期処理は
bodyからではなく、.task、.onAppear、または明示的なアクションにひも付けられていますか?
SwiftUI のビューは、UI を記述する値です。長期間存続する UIKit 形式のオブジェクトとして扱わないでください。
レビューワークフロー
広範な変更を提案する前に、関連する最小限のコードパスを確認します。
次の順に確認します。
- 安定した、意図が明確なアイデンティティ。
body内の高コストな処理。- 広範な状態やモデルの読み取り。
- 状態の所有者とライフタイム。
- リスト、行、ページネーションの構造。
- クロージャを多く含む入力、カスタムバインディング、不要な型消去。
- 繰り返し表示されるコンテンツのレイアウト、描画、アニメーションのコスト。
- 非同期処理のライフサイクル、キャンセル、メインアクター上の処理。
- 確認が有効な場合のプロファイリングやデバッグ用の計測。
アーキテクチャ全体の書き換えよりも、対象を絞ったリファクタリングを優先します。
根拠に関するルール
以下は必ず区別します。
- 静的コードレビューで見つかった問題
- 想定されるリスク
- 仮説
- 測定結果
- ユーザーから提供された根拠
- ツールによって得られた根拠
ユーザーから根拠が提供されている場合、または実際にプロファイリングコマンドを実行した場合を除き、時間の数値を捏造したり、プロファイリング結果を断定したりしないでください。
次のように述べます。
この親ビューはモデル全体を読み取っているため、そのモデルに変更があると、画面の広い範囲が無効化される可能性があります。
次のような言い方は避けます。
これには500ミリ秒かかります。
よくある危険信号
更新やスクロールのパスに次のパターンが現れた場合は、問題として指摘します。
.id(UUID())やvar id: UUID { UUID() }など、不安定なID- 変更可能なコレクションに対する、インデックスベースのアイデンティティ
body内での並べ替え、フィルタリング、グループ化、書式設定、解析、デコード、データベースの読み取り- 表示対象の行をあらかじめ準備せず、
ForEach内でフィルタリングすること - 1つの巨大なモデルをすべての子ビューに渡すこと
- 多数の状態読み取りを隠している、広範な計算プロパティ
- 繰り返し表示される大規模なコレクション内での
AnyView - キーパスバインディングで対応できる箇所での、カスタム
Binding(get:set:) - 行ビューに格納された、視覚要素ではないクロージャが多数あること
- すべての行における
GeometryReader、プリファレンス、重いシャドウ、マスク、ぼかし、オーバーレイ bodyから直接開始される非同期処理- 行内の、ガード処理のない
.onAppearによるページネーションのトリガー
リファクタリングのガイドライン
原因に対処する最小限の修正を行います。
- アイデンティティを安定させます
- コストの高い変換処理は
bodyの外に移します - 繰り返し実行されるレンダリング処理の外で、レンダリングに適したモデルを準備します
- 状態は、それを所有するコンポーネントの近くに移します
- 大きなビューは、依存関係に焦点を当てたサブビューに分割します
- 行の入力と繰り返しの構造をシンプルにします
- 変換が不要な場合は、カスタムのクロージャーバインディングよりキーパスバインディングを優先します
- 視覚的な等価性が明確で、再計算よりコストが低い場合にのみ
.equatable()を使用します - 変化する入力に処理が紐づいていて、自動的にキャンセル・再起動する必要がある場合は
.task(id:)を使用します - より低レベルの制御が必要な、本当に処理負荷の高い箇所に限り、UIKit の使用を検討します
.equatable()、メモ化、キャッシュを一律の対策として使用しないでください。まず、無効化やレンダリングの問題を説明してください。
リファレンスの参照
より詳しい情報が必要な場合にのみ、リファレンスを参照します。
references/identity-and-state.md— アイデンティティ、.id、ForEach、@State、@StateObject、@ObservedObject、所有する監視可能なモデルreferences/observation-and-dependencies.md— Observation、ObservableObject、広範な依存関係、環境からの読み取りreferences/body-cost-and-render-models.md— ソート、フィルタリング、フォーマット、派生データ、レンダリングモデルreferences/lists-pagination-and-rows.md—List、ScrollView、LazyVStack、行、ページネーション、スクロールreferences/closures-bindings-and-equatable.md— クロージャー、バインディング、.equatable()、アクションハンドラーreferences/layout-drawing-and-animation.md— レイアウト、描画、モディファイア、アニメーションの引っかかりreferences/async-lifecycle-and-mainactor.md—.task、.onAppear、キャンセル、MainActorreferences/profiling-validation.md— Instruments、xctrace、サインポスト、XCTest、MetricKit
回答形式
コードレビューでは、次の形式で回答します。
- 主な問題
- SwiftUI で重要となる理由
- リスクレベル
- 推奨するリファクタリング
- 必要に応じたコード例
- 確認が必要な場合に測定する内容
プロファイリングの依頼には、次の形式で回答します。
- シナリオ
- 仮説
- ツールまたはプローブ
- 確認する内容
- 修正前後の比較方法
具体的に回答してください。「SwiftUI は遅い」とは言わないでください。アイデンティティ、依存関係、レンダリング、レイアウト、描画、アニメーション、ライフサイクルのどの問題なのかを説明してください。
最終原則
コード上で変更の局所性が明確になると、SwiftUI のパフォーマンスは向上します。