mcpField
S
swiftui-debugging

swiftui-debugging

github.com/mengto開発7.1k65 回インストール5 日前に更新
リポジトリ

swiftui-debugging について

SwiftUI 開発者向けのデバッグスキルです。プロファイリングやビューの ID 確認、軽量な計測を通じて、性能問題を根拠に基づいて診断し、対象を絞った修正につなげます。

主な機能

  1. 01ビュー body の再評価を追跡
  2. 02ビュー ID の変化を診断
  3. 03リストとグリッドの読み込みを確認
  4. 04Instruments とログを活用
  5. 05対象を絞った性能改善

活用シーン

  1. 01予期しない body 更新の調査
  2. 02状態リセットや表示の繰り返しを解決
  3. 03スクロールや初回読み込みの遅さを特定
  4. 04負荷の高い処理を body の外へ移動

インストール

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

$npx skills add https://github.com/mengto/skills --skill swiftui-debugging

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

詳細

SwiftUI のデバッグ

このスキルでは、SwiftUI のパフォーマンスに関する問題を、小さなエビデンス確認ループに落とし込みます。何が変わったのかを特定し、SwiftUI がビューを再作成しているのか、単に再評価しているのかを確認してから、最小限の修正を適用します。

ワークフロー

  1. 症状を再現するか、発生箇所を特定します。

    • 編集する前に、名前が挙がっているビュー、モデル、リスト/グリッド、またはモディファイアの連鎖を検索します。
    • 対象のビューや操作をリポジトリから推測できない場合に限り、最小限の再現例を求めます。
    • 当て推量よりも、プロファイラのトレース、_printChanges() の出力、コンソールログ、または明確な操作手順を優先します。
  2. 診断方法を選びます。

    • 予期しない body の呼び出しや、ノイズの多い _printChanges():references/body-reevaluation.md を読みます。
    • 状態のリセット、onAppear の繰り返し、奇妙なアニメーション、フォーカスの喪失、またはスクロール位置のリセット:references/view-identity.md を読みます。
    • 多数の項目がある場合の遅いリスト、グリッド、スクロールビュー、または初回読み込み:references/lazy-loading.md を読みます。
    • AnyView、body 内でのオブジェクト生成、コストの高いソート/フィルタリング、過大な画像、または状態の繰り返し更新:references/common-pitfalls.md を読みます。
  3. 大規模な書き換えの前に、最小限の計測を行います。

    • 問題が疑われる最小のビューで let _ = Self._printChanges() を使います。
    • コードの調査だけではコストを説明できない場合は、Instruments の SwiftUI テンプレートを使います。
    • コストの高い処理の周辺でカウントを記録するには、os.Logger または os_signpost を使います。
  4. 無効化を減らす、ID を維持する、または処理を移動して修正します。

    • 状態を、実際にそれを使用するビューに移します。
    • 大きなビューを分割し、無関係な状態変更によってコストの高いサブツリーが再評価されないようにします。
    • ForEach と .id() には安定した識別子を使います。
    • 大規模なコレクションでは、先行して全項目を生成するコンテナーを List または遅延スタック/グリッドに置き換えます。
    • 負荷の高いフォーマット処理、デコード、ソート、フィルタリング、画像の準備を body の外に移します。
  5. 症状が解消したことを確認し、ユーザーが残すことを希望していない限り、一時的な計測コードを削除します。

クイックトリアージ

症状最初に疑う点参考資料
無関係な値が変わったときに body が実行される過剰な監視、親ビューの再作成、高すぎる位置にある状態body-reevaluation.md
_printChanges() に @identity changed と表示される不安定な .id()、条件分岐による構造の変更view-identity.md
スクロールビューが一度に何百もの行を生成するScrollView 内の VStack/HStack、遅延コンテナーがないlazy-loading.md
同じコンテンツで onAppear が繰り返されるID の変動、または遅延セルの再利用view-identity.md、lazy-loading.md
フィールドへの入力で画面全体が更新される広範囲に影響する ObservableObject、高すぎる位置に保存された状態body-reevaluation.md
初回読み込みやアニメーションが途切れるbody 内の高負荷な処理、画像のデコード、先行レイアウトcommon-pitfalls.md
動的なビュー型の周辺で差分判定の精度が低いように見えるAnyView または型消去された分岐common-pitfalls.md

便利なツール

Self._printChanges()
var body: some View {
    let _ = Self._printChanges()
    // view content
}

一般的な出力は次のように解釈します。

出力意味
@self changed親ビューがこのビュー値を再作成しました。親の無効化と入力値の等価性を確認してください。
@identity changedSwiftUI がビューを破棄して再作成しました。.id()、ForEach の ID、分岐を確認してください。
_property changed保存されたプロパティ、状態、バインディング、または環境値が変わりました。
Instruments

Xcode の SwiftUI テンプレートを使って、ビュー本体のカウント、ビューのプロパティ変更、Core Animation のコミットを調べます。カウントまたは継続時間で並べ替え、遅い操作を再現して、最も負荷の高いビュー型に編集を集中させます。

カスタムログ

簡単なローカルカウントには os.Logger を、Instruments でタイムラインとの相関を確認する必要がある場合は os_signpost を使います。

レビューチェックリスト

  • UUID()、Date()、ランダム値、変更可能な配列インデックスなど、不安定な .id() の値は使用しません。
  • ForEach では、安定した一意のモデル識別子を使用します。
  • 同じビューの修飾子を切り替えることだけを目的として、条件分岐を使用しません。
  • 大規模なコレクションには、List、LazyVStack、LazyHStack、LazyVGrid、または LazyHGrid を使用します。
  • ビューが監視するのは、実際に表示または変更するモデルのプロパティだけです。
  • デプロイメントターゲットが対応している場合は、広範な ObservableObject よりも @Observable を優先します。
  • フォーマッター、デコーダー、述語、正規表現、ビューモデル、画像のデコードは body 内で作成しません。
  • コストの高いフィルタリング、ソート、レイアウト計算は、変更時、キャッシュされた状態、または適切な場合はメインアクター以外で実行します。
  • 一時的な _printChanges()、print ログ、サインポストは、最終納品前に削除するか、意図したものであることを明確にします。

API の利用可能状況

API /手法最低プラットフォーム
Self._printChanges()iOS 15 / macOS 12 世代の SwiftUI 診断機能
ObservableObjectiOS 13 / macOS 10.15
@ObservableiOS 17 / macOS 14
LazyVStack、LazyHStack、LazyVGrid、LazyHGridiOS 14 / macOS 11
.id()iOS 13 / macOS 10.15
TimelineViewiOS 15 / macOS 12
Instruments の SwiftUI テンプレートXcode 14 以降

参考資料

  • references/body-reevaluation.md:依存関係の無効化、_printChanges()、監視範囲、状態の配置。
  • references/view-identity.md:構造的なアイデンティティ、.id()、ForEach、分岐のアイデンティティ、状態の喪失。
  • references/lazy-loading.md:即時読み込みと遅延読み込みのコンテナ、リスト/グリッドの選択、スクロールのパフォーマンス、遅延読み込みの注意点。
  • references/common-pitfalls.md:AnyView、オブジェクトの割り当て、コストの高い body の処理、画像のデコード、冗長な状態、非表示のビュー。
  • references/upstream-license.md:元資料の出典表示と MIT ライセンスに関する通知。

コメント