ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
コミットフェーズでの滞りを見つけ修正する
レンダリングループのコミットフェーズをトラブルシューティングして、App内でスムーズなアニメーションをレンダリングする方法について確認します。このフェーズの仕組みを深く掘り下げ、滞りの原因となるものを明らかにし、それらを排除し、完全に回避するためのInstrumentsの使用方法についても確認します。
リソース
関連ビデオ
Tech Talks
-
ダウンロード
コミットフェーズにおける アニメーションHitchの発見と対処法 チャールズです 今日はRender Loopの コミットフェーズにおける― アニメーションHitchについて話します
iOSではビューの表示に Render Loopを使用します タッチイベントはAppに送られ ビューの変更に反応し― ビューはiOSにより画面に表示されます
今日はRender Loopのコミットフェーズの アニメーションHitchの発見と対処法に注目します
Render LoopとHitchについては "Explore UI Animation Hitches and The Render Loop"の動画をどうぞ
まずはコミットトランザクションを 確認します
そしてInstrumentsを用いてHitchを見つけ
コミットHitchを避けるための助言をします ではコミットトランザクションとは? イベントに備えて待機する Appのビューの階層構造の例です タッチイベントにビューが反応し 背景の色やサブビューのフレームを変え イベントを処理します 次のコミットトランザクションの間 必要なレイアウトや画面をシステムが記録します
コミットトランザクションの間 必要な画面やレイアウトは― drawRectやlayoutSubviewsにより 適宜アップデートされます
コミットトランザクションには どんな段階があるか見てみましょう 4段階に分かれます レイアウト 画面 準備 そしてコミットの段階
レイアウトの段階では レイアウトが必要なビュー全てに layoutSubviewsが必要です 必要なレイアウトにマークをつけるなら ビューの位置を変えたり ビューを追加もしくは削除します あるいはsetNeedsLayoutを ビューに使うこともできます
ディスプレイの段階では ディスプレイを必要とする全てのビューに drawRectが使われます 必要なディスプレイを表示するには drawRectをオーバーライドする ビューの階層構造を追加します もしくはsetNeedsDisplayを使います 準備の段階で デコードされていない画像は この段階でデコードされます こういった操作は 画像が大きいと時間がかかります
また 画像のカラーフォーマットが 直接GPUと連動できない場合 この段階で変換されます この場合 オリジナルにポインターを送らず 画像がコピーされるので 追加で時間もメモリも必要になります Appの画像の最適化を詳しく学ぶなら "Image and Graphics Best Practices"の 動画をどうぞ
コミットの段階では ビューの階層構造は繰り返し包括され レンダーサーバーに送られます ビューの階層構造が深いと 包括に時間がかかります コミットトランザクションの説明はここまでとし 次のテーマに移ります Instrumentsを用いたHitchの見つけ方 Xcode 12ではAppのHitchプロファイリングのため 新しいInstruments のテンプレートをリリース これによりRender Loopが可視化され Hitchのあるフレームを見つけやすくなります
App中のHitchの例を見てみましょう App上でのスクロールは Instrumentsで履歴を記録 スクロールのパフォーマンスの履歴で 見つかったHitchを確認できます
Hitch16について詳しく見てみましょう
フレームを構成するのに必要な Render Loopの段階に対応するトラックが 左側にあるのが分かります
Hitchのトラックに Hitchと持続時間が表示されています
User Eventsのトラックには Hitchのあるフレームとともにイベントが表示
Commitsのトラックにはコミットフェーズと この段階で行われる処理が表示されます
レンダーとGPUについては パトリックが― "Demystify and Eliminate Hitches in the Render Phase"の動画で説明します
Frame Lifetimesのトラックでは フレームのHitchを構成する時間を表示 Built-in Displayのトラックでは ディスプレイ上のフレーム全てと― 垂直同期のイベントが表示されます
Hitchの時間の開始と Frame Lifetimeを比較すれば― フレームがディスプレイ用に 待機すべきだった時間間隔を可視化できます
この時間間隔がAcceptable Latencyです あとはHitchの持続時間です
選択したトラックの下に Hitchについて詳しい数値が表示されます デモ版のAppにはHitchが多くありますが ここではHitch16に注目します
Hitchの持続時間がここ Accetable Latencyも分かります
Hitchのタイプもわかります Hitchのタイプは フレームが遅れた段階や 調査のタイミングのヒントになります たとえば ここでフレームのHitchは コミットとGPUの段階で起きたのが分かります
コミットフェーズで何のコードに 時間がかかったか知りたいのですが 幸いアニメーションHitchのテンプレートに Time Profilerがあります これでHitchの発生時に 実行されていたコードが分かります ここからは調査したい時間間隔を選び― その時のプロセスを探ります メインスレッドから このプロセスを選び―
コールツリーを表示します
これで どのcallに時間がかかるかを 分析できます このツリーは コミットトランザクションで始まりました そしてQSTEM CollectionViewCellの update Tagsに10ミリ秒かかってます
ではAppの場合なら?
一般的なCollectionViewから成り UIImageViewを用いて セルには サムネイル画像が表示されています テキストにUILabelが使われ タグにカスタマイズされた TagLabel viewが使われます QSTEM CollectionViewCell classの 実例を見ましょう このメソッドはどこのことを指すのか menuItemに property observerが 表示されています
これが update Tagsを呼び出す時の シナリオは2つあります 有効な menuItemが設定されているか ゼロに設定されているか 1つめの場合 表示したいタグの列を 分類します 2つめの場合 残ったタグを取り除くため 空の列を分類します 実行中の update Tagsを 詳しく見てみましょう 空のタグの列に備えて 全てのビューの階層構造のビューを排除します 必要なら StackViewを作ります そして各タグにTagLabelを作るか 再利用をします 前に使用した時のタグが 新しいタグより多くならないよう― 既存の未使用のタグは全て取り除きます 実行した時の流れが分かったところで calling scopeに戻り 問題を予測しましょう QSTEM CollectionViewCellは prepareForReuse methodをオーバーライドし 再利用のためにセルがデキューされる時に 使われます このメソッドでは menuItemをnilに設定します これにより2つ目のシナリオの 状況になります そこで再利用はせずに セルのビューの階層構造から 全てのTagLabelsを取り除きます
つまり全てのデキューされたセルから 使用済みのlabel subviewを取り除き 全てのlabelを表示するのに必要な ビューを再インスタンス化します
最善の処置ではなく Hitchの原因にもなり得ます 解決法はシンプルです menuItemを消去する必要はなく― prepareForReuse のメソッドを 排除するだけです また 新しいセルのmenuItemの設定には 再利用のロジックを利用し 厄介なビューの階層構造の操作を避けます 対処後に新たに記録を残すと 最初の記録と比べて Hitchの数が激減しているはずです InstrumentsのTime Profilerは 時間のかかるコードやHitchの原因発見に有用です Time Profilerについては "Using Time Profiler in Instruments"の 動画をどうぞ
Instrumentsを用いたAppの プロファイリングを学びましたね 続いてコミットフェーズにおける Hitchの避け方です ルール1 ビューを軽くしておくこと これでCALayerのプロパティを利用でき GPUの速度が上がり CPUのカスタマイズされた描画を 避けることができます パフォーマンスについて 計測することを忘れずに システムに余計な負荷がかかるので drawRectでの無意味な作業は避けましょう 次のトランザクションで 時間もメモリも余計にかかります ビュー追加や削除など 階層構造の操作を避け できるだけビューの再利用を心がけましょう アニメーションの間 特定のビューを止めたいなら ビューの非表示の機能を利用しましょう このほうが楽です ルール2 手間のかかかる余分なレイアウトを減らすこと レイアウトのアップデート時には setNeedsLayoutがお勧めです layoutIfNeededは トランザクション存続時間を拡大させ Hitchを引き起こします レイアウトのアップデートは 次のRun Loopを待ってもいいでしょう 解決法が複雑にならないよう 制限はなるべく減らしましょう ビューの無効化は それ自体や子供に限り 兄弟姉妹や親のビューに適用しないこと これをすると 無効化を繰り返すことになります performance layoutや 画像やグラフィックスについて学ぶなら WWDCの動画で2つお勧めがあります
コミットトランザクションの パイプラインを理解したので 面倒なコミットを避けられるでしょう Instrumentsの 新しいAnimation Hitches templateを利用すれば Hitchを発見し調査できます コミットHitchの予防策も学びました prepareForReuseに余計な作業をさせず ビューの階層構造を浅く軽くすること 面倒で余分なレイアウトも避けましょう さらにRender Loopの 次の段階を学ぶため― "Demystify and Eliminate Hitches in the Render Phase"の動画を見てください 以上です
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。