レイアウトキャッシュとパフォーマンス
効率化のためにレイアウトキャッシュを使用します。
「レイアウトキャッシュとパフォーマンス」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。
レイアウトキャッシュが必要な理由
SwiftUIは、1回のレイアウトパス中にsizeThatFitsとplaceSubviewsを何度も呼び出すことがあります。
計算コストが高い場合は、キャッシュを使うと一度だけ計算して再利用でき、繰り返しの処理を避けられます。
Cache関連型
LayoutプロトコルにはCache関連型があり、デフォルトはVoidです。独自の構造体を定義して、事前計算した結果を保存できます。
struct FlowLayout: Layout {
struct CacheData {
var sizes: [CGSize] = []
}
typealias Cache = CacheData
}makeCache
makeCache(subviews:)を実装して初期キャッシュを構築します。SwiftUIはレイアウトメソッドの前にこれを1回呼び出すため、事前の測定を行う場所として利用できます。
func makeCache(subviews: Subviews) -> CacheData {
let sizes = subviews.map { $0.sizeThatFits(.unspecified) }
return CacheData(sizes: sizes)
}キャッシュの読み取り
これでレイアウトメソッドはinoutパラメータとしてcacheを受け取ります。各子を再測定する代わりに、事前計算した値を読み取ります。
func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout CacheData) -> CGSize {
let height = cache.sizes.map(\.height).max() ?? 0
let width = cache.sizes.reduce(0) { $0 + $1.width }
return CGSize(width: width, height: height)
}updateCache
サブビューの集合が変わると、SwiftUIはupdateCache(_:subviews:)を呼び出します。デフォルト実装はmakeCacheを使って再構築しますが、オーバーライドして段階的に更新することもできます。
func updateCache(_ cache: inout CacheData, subviews: Subviews) {
cache.sizes = subviews.map { $0.sizeThatFits(.unspecified) }
}updateCacheが実行されるタイミング
updateCacheは、サブビューの数またはアイデンティティが変わったときに実行されます。すべてのジオメトリ変更のたびに実行されるわけではありません。キャッシュするのはサブビューに依存するデータだけにし、提案されたサイズに依存するデータはキャッシュしないでください。
提案に依存しないデータだけをキャッシュする
よくあるバグは、提案されたサイズに依存する結果をキャッシュすることです。呼び出しごとに提案が変わる可能性があるため、サイズに依存する結果は盲目的にキャッシュせず、再計算する必要があります。
// OK to cache: intrinsic child sizes
// NOT OK to cache: row breaks (depend on proposed width)固有サイズのキャッシュ
安全なパターンは、コストの高いsizeThatFits(.unspecified)の結果をキャッシュし、現在の提案を使って低コストな折り返し計算を呼び出しごとに実行することです。
struct CacheData { var intrinsic: [CGSize] = [] }
// wrapping uses cache.intrinsic + current maxWidth早すぎる最適化を避ける
単純な子が少数しかない場合、測定は低コストであり、キャッシュによって複雑さが増します。まずプロファイリングを行い、測定に本当にコストがかかる場合(テキスト、画像、入れ子のレイアウト)にだけキャッシュを使用してください。
キャッシュと値セマンティクス
キャッシュはSwiftUIが所有し、inoutで渡されます。SwiftUIがライフタイムを安全に管理できるよう、ビューへの参照を持たない単純な値型にしてください。
struct CacheData {
var sizes: [CGSize] // value types only
}効果の測定
SwiftUI Instrumentまたは単純なカウンターを使い、キャッシュによって実際に測定呼び出しが減っていることを確認してください。測定せずに行う最適化は推測にすぎません。
確認テスト:レイアウトキャッシュ
レイアウトキャッシュについて理解度を確認します。
まとめ:レイアウトキャッシュとパフォーマンス
LayoutプロトコルのCache関連型は、makeCacheで構築され、updateCacheで更新されます。子の固有サイズのような、提案に依存しないコストの高い処理の結果を保存します。
提案に依存する低コストな計算は、呼び出しごとに実行してください。キャッシュは参照を持たない値型にし、早すぎるキャッシュを避け、複雑さを加える前にプロファイリングで効果を確認します。
よくある質問
「レイアウトキャッシュとパフォーマンス」レッスンは無料ですか?
はい。「レイアウトキャッシュとパフォーマンス」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。
「レイアウトキャッシュとパフォーマンス」で何を学びますか?
効率化のためにレイアウトキャッシュを使用します。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Swift Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「レイアウトキャッシュとパフォーマンス」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSwift Academyレッスンでコードを書いて実行できますか?
はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Layoutプロトコルの基礎
- サブビューの測定
- Flow Layoutの構築
- レイアウトキャッシュとパフォーマンス