記事
Creating Performant Scrollable Stacks
(パフォーマンスの高いスクロール可能なスタックの作成)
スクロールビュー、スタックビュー、lazy スタックを使用して、多数の繰り返しビューを効率的に表示します。
概要
多くの場合、あなたのアプリは、デバイスのスクリーンに表示されるスペースよりも多くのデータをコンテナビュー内に表示する必要があります。水平スタックと垂直スタックは、ビューまたはビューのグループを繰り返すのに適した良いソリューションですが、スクロールするための組み込みのメカニズムはそれらにはありません。ScrollView 内でスタックを包み込むことでスクロールを追加し、パフォーマンスの問題が発生したときに lazy (遅延した) スタックに切り替えることができます。
スクロール可能なコンテナ内にビューのグループを表示
繰り返しビューまたはビューのグループを実装することは、ScrollView 内の HStack または VStack でそれらを包み込むのと同じくらい簡単です。
ScrollView(.horizontal) {
}
.frame(maxWidth: 500)
上記のサンプルコードの ProfileView の固有のコンテンツサイズが 200 x 200 ポイントの場合、 frame(minWidth:idealWidth:maxWidth:minHeight:idealHeight:maxHeight:alignment:) ビュー修飾子が ScrollView に適用する最大幅は500ポイントで、スタックをその内側でスクロールさせます。
スタックを使用してビューを一緒にグループ化する方法の手ほどきについては、スタックビューを使用したレイアウトのビルド を参照してください。
データのビューを繰り返す
ForEach を使用して、アプリ内のデータのビューを繰り返します。profile 配列内のプロファイルデータのリストから、ForEach を使用して、HStack 内の配列内の要素ごとに 1 つの ProfileView を作成します。
ScrollView(.horizontal) {
}
.frame(maxWidth: 500)
注意
ForEach を使用する場合、反復する各要素は一意に識別可能 (identifiable) でなければなりません。要素をIdentifiable のプロトコルに準拠させるか、 init(_:id:content:) の id パラメータとして一意の識別子 (ID) にキーパスを渡します。
多数のビューの Lazy (遅延した) スタックを検討する
3 つの標準スタックビューである HStack、VStack、および ZStack はすべて、表示する時に含まれているビュー階層をロードし、多数のビューを一度にロードすると、実行時のパフォーマンスが低下する可能性があります。
上記の例では、ProfileView は、入れ子にされたスタックビュー、テキストラベル、および画像ビューで構成される複合ビューです。一度に多数のプロファイルをロードすると、顕著な速度低下が発生します。
スタック内のビューの数が増えるにつれて、HStack と VStack の代わりに LazyHStack と >LazyVStack を使用することを検討してください。 Lazy スタックは、それらのサブビューを必要に応じてロードおよびレンダリングし、多数のサブビューをロードするときにパフォーマンスを大幅に向上させます。
スタックビューと lazy スタックは同様の機能を備えており、互換性があるように感じるかもしれませんが、それぞれ異なる状況で長所があります。スタックビューは子ビューを一度に全てロードし、システムがそれらのロード時にすべてのサブビューのサイズと形状を認識しているため、レイアウトを高速かつ信頼性の高いものにします。lazy スタックは、サブビューが表示されたときにのみシステムが構造を計算するため、パフォーマンスとある程度のレイアウトの正確さを交換します。
使用するスタックビューの型を選択するときは、常に標準のスタックビューから始めて、あなたのコードのプロファイリングでパフォーマンスが向上する価値があることが示された場合にのみ、lazy スタックに切り替えてください。
パフォーマンスの問題を見つけるためのプロファイル
使用すべきスタックのタイプを検討するときは、Instruments ツールを使用してあなたのアプリケーションのプロファイルを作成し、スタック内に多数のビューがロードされているユーザーインターフェイスコードの領域を鑑別します。
SwiftUI ビューのロードをプロファイリングするには、[Xcode Product(Xcode 製品)] メニューから [Profile(プロファイル)] を選択し、SwiftUI プロファイリングテンプレートを選択して、Instruments ツールを開きます。このテンプレートは、[View Body(本体の表示]、[View Properties(プロパティの表示)]、[Core Animation Commits(コアアニメーションの委任)]、および [TimeProfiler(タイムプロファイラー)] の 4 つの Instruments をロードします。これらの Instruments の組み合わせは、アプリを高速化する機会を見つけるための良い出発点を提供します。
注意
iOS シミュレータを使用してあなたのコードをプロファイリングしないでください。パフォーマンステストには、常に実際のデバイスを使用してください。
上記のコードをプロファイリングすると、[View Body] Instrument は、1,000 個の ProfileView インスタンスが HStack と同時にメモリにロードされることを示します。また、システムが各プロファイルをロードするのと同じ数の Image ビューがロードされることを確認できます。
この場合の解決策は、以下のコードが示すように、HStack を LazyHStack に置き換えることです。
ScrollView(.horizontal) {
}
.frame(maxWidth: 500)
別のトレースを実行すると、4 つの ProfileView インスタンスのみが表示されて開始されるため、最初にロードされたビューの数が大幅に減少します。[Total Duration(合計期間)] 列にも対応する減少が見られます。
Instruments ツールの使用の詳細については、アプリのパフォーマンスの向上 を参照してください。
以下も見よ
Lazy スタック
コンテンツを lazy スタックビュー内の論理セクションに分割します。
その子を水平方向に伸びる線に配置し、必要な場合にのみ項目を作成するビュー。
その子を垂直方向に伸びる線に配置し、必要な場合にのみ項目を作成するビュー。