Successfully reported this slideshow.
Your SlideShare is downloading. ×

BuriKaigi2018

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 34 Ad

More Related Content

Slideshows for you (20)

Similar to BuriKaigi2018 (11)

Advertisement

Recently uploaded (20)

Advertisement

BuriKaigi2018

  1. 1. 仮想化つらい、考えたくない - UWPのListViewの話 2018/2/3 Burikaigi 2018 (.NET) tmyt
  2. 2. $ whoami tmyt (a.k.a. 津守) 最近はフリーランスをやっています Microsoft MVP for Windows Development Twitter: @tmyt 好きなWindows 10の機能: WSL
  3. 3. 今日やること UWPでのListViewの仮想化 仮想化の失敗事例 仮想化で成功したい 仮想化つらいを共有したい
  4. 4. こんなことがありました
  5. 5. 仮想化されない
  6. 6. 仮想化されない 子要素の数 なんだこれ
  7. 7. 仮想化されないと メモリ使用量が多すぎる 描画速度が遅い スクロールのパフォーマンスが悪い つまり最悪なアプリの出来上がり
  8. 8. 仮想化のおさらい
  9. 9. 仮想化しない ViewPortの外もイン スタンスが存在する ViewPortの外もイン スタンスが存在する
  10. 10. 仮想化する ViewPortの外は インスタンスが 存在しない ViewPortの外は インスタンスが 存在しない
  11. 11. ListViewの仮想化とは 表示されてない個所を描画しないことでコストを削減  メモリ  CPU  etc.. 項目数が増えれば増えるほどパフォーマンスに影響大 正しく仮想化する必要がありますね!
  12. 12. UWPでの仮想化 ピクセル単位で仮想化できるようになりました ItemContainerを基準として仮想化されている  ListView → ListViewItem ItemContainerを使いまわすパネルが実装されている  VirtualizingStackPanel  VirtualizingWrapPanel  ItemsStackPanel  ItemsWrapGrid ItemsPanelが仮想化に対応している場合たいていはいい感じに 仮想化される
  13. 13. 仮想化に失敗するとき
  14. 14. ListViewが仮想化される条件 主に2個 1. 仮想化されるパネルを使用していること 2. ScrollViewerが有限の高さ/高さを持つこと つまり通常問題はない
  15. 15. たとえばこれはだめ <ScrollViewer> <ListView /> </ScrollViewer> ScrollViewerの子要素になることでListViewの幅/高さが無限になるので仮想化されない
  16. 16. なおしかた <ScrollViewer> <ListView Height=“10”/> </ScrollViewer> 有限な値にする ListViewの高さが明示的に指定されるので高さの計算で無限大にならない
  17. 17. たとえばこれもだめ <ListView> <ListView.ItemsPanel> <ItemsPanelTemplate> <StackPanel /> </ItemsPanelTemplate> </ListView.ItemsPanel> </ListView>
  18. 18. たとえばこれもだめ <ListView> <ListView.ItemsPanel> <ItemsPanelTemplate> <StackPanel /> </ItemsPanelTemplate> </ListView.ItemsPanel> </ListView> ListViewのItemsPanelが仮想化対応パネルじゃないので仮想化されない
  19. 19. なおしかた <ListView> <ListView.ItemsPanel> <ItemsPanelTemplate> <ItemsStackPanel /> </ItemsPanelTemplate> </ListView.ItemsPanel> </ListView> 仮想化パネルを使う
  20. 20. それでも仮想化が うまくいかない…
  21. 21. どうしても仮想化がうまくいかない… 高さも指定した 仮想化対応パネルも使っている でも仮想化されない わからない 1年悩んだけど全く分からない
  22. 22. その正体はItemTemplateSelector
  23. 23. これなに 要素によって適用するDataTemplateを変更したいときに使う DataTemplateSelectorクラスに任意のDataTemplate選択アルゴ リズムを実装して使う  Ex)項目の型、項目のプロパティ うまく作るとすごい便利  普段はXAMLで書ける仕組み作って使ってます
  24. 24. こういう風に使ってます
  25. 25. これの問題点 これを消すとうまく仮想化される 消してないとうまく仮想化されないことがある 半ばあきらめかけてMSDNを確認してみると
  26. 26. MSDNを確認… うそでしょ なにそれ
  27. 27. ChoosingItemContainerイベント 項目を表示させるためにコンテナが必要になったときに呼ばれ るイベント このイベントでいい感じにインスタンスを生成してあげるとう まい具合に仮想化がうまくいくことがある 少なくともItemTemplateSelectorを呼ぶよりはうまくいく確率 が高い(当社比)
  28. 28. こんな実装でいいらしい var template = Selector.SelectTemplate(args.Item); if (args.ItemContainer != null && args.ItemContainer.ContentTemplate != template) { args.ItemContainer.ContentTemplate = template; } if (args.ItemContainer == null) { args.ItemContainer = new ListViewItem { Style = sender.ItemContainerStyle, ContentTemplate = template, }; } args.IsContainerPrepared = true;
  29. 29. 雰囲気うまくいく理由 常に再利用できていそう  DataTemplateを差し替えているので違うTemplateでも使いまわせてる  ItemTemplateSelectorを使用する場合はDataTemplate差し替えをしてい ない雰囲気がある パフォーマンスもそれなりに出ている  ListViewItemのDataTemplateをいきなり変更しても案外大丈夫らしい  ペナルティあっても仮想化されないときのパフォーマンス低下よりは まし
  30. 30. 雰囲気うまくいった結果 1/3になった よさそう
  31. 31. 仮想化の気持ちになってみると… ItemTemplateSelectorの実装は予測できない  つまり項目に対するDataTemplateに何が使用されるか予測できない  Ex)型が同じなら同じでいい?  だめ。内部データで判別してるかも。 ListViewItemのテンプレートが予測できない  仮想化するのかなり難しい  毎回評価するしかない  出てきたDataTemplateと同じListViewItemで使ってないコンテナを探すしかない 確かにあきらめたくなる
  32. 32. まとめ
  33. 33. まとめ 仮想化はたいていうまくいく うまくいかなかったときかなり辛い 原因はそんなに多くない  ListViewの幅/高さは有限であるか  パネルは仮想化に対応しているか  予測できないDataTemplateを使っていないか それでもだめなら仮想化の気持ちになってみる
  34. 34. おまけ ItemTemplateSelectorが場合によって微妙な挙動することを 知ったので現在はBehaviorで対処しています。 http://bit.ly/2DOXbdN

×