Angular 製高機能グリッドのパフォーマンス問題に立ち向かっている話
2018/11/25 Sun
HTML5 Conference 2018
@TatsushiKiryu
About me
最近よく聞く話
最近よく聞く話
- Flash や Silverlight で作られたアプリをHTML5 ベースに移行したい
- IG:Angular で SPA でいきましょう!
Angular といえばAngular Material
Angular Material が
苦手なものもある
- グリッドでいろんなことしたい
- 大量データを表示したい
- Excelライクに操作したい
- キーボードナビゲーション
- グルーピング
- 列固定
- 列リサイズ
- 列ごとのフィルタリング
igx-grid from Ignite UI for Angular
ページング
フィルタリング
ソーティング
選択
集計
グルーピング
グリッド内検索
ツールバー
表示密度の変更
列移動
列固定
列サイズ変更
列非表示
複数列ヘッダー
条件付きセルスタイル
インライン編集
インライン行編集
一括編集
Excel エクスポート
Excel からの貼り付け
キーボードナビゲーション
そして、速い。
様々な業務利用シナリオをカバー
igx-grid デモ
ベストマッチ
- Angular Material が苦手とする範囲(業務向けの機能)は Ignite UI for Angular で補完できる
- どちらも Material Design に準拠したスタイルで、UI の親和性も高い
Angular Material + Ignite UI for Angular
でより効率よく開発することができる!
igx-grid
速さのヒミツ
igx-grid 速さのヒミツ
- UI 仮想化
- スクロール領域において、Viewportのみ描画することによってレンダリングコストを減らす仕組み
- Viewport内に描画されたDOMは使い回し
UI仮想化
- Itemの高さ x 件数
=> scroll 量を算出 - scroll イベントに応じて、DOMの情報を書き換え
見えている部分(Viewport)+ α
だけDOMをレンダリング
igxFor ディレクティブ
- Ignite UI for Angular では UI 仮想化の仕組みを、igxFor として切り出した
- igx-grid は縦、横の両方向において igxFor を使って UI 仮想化を実現。
- どれだけデータ量が増えても、レンダリングされる DOM は Viewport 部分のみ。
igxFor ディレクティブ
- 大量データを繰り返し表示するシナリオに最適
- データグリッド -> igx-grid 内部使用
- コンボ -> igx-combo 内部使用
- リストビュー -> igx-list で使用可能
- div, li タグなどとも使用可能
ところで
- Angular Material にも cdkVirtualScroll というのがあるけど、これを使えば、Angular Material だけで十分なんじゃない?
cdkVirtualScroll の状況
- mat-table との統合はまだサポートされていない
- なんとかして組み込もうという試みはあるhttps://github.com/angular/material2/issues/10122
ということで
- 大量データを扱う業務アプリにとって、UI 仮想化はパフォーマンス向上になくてはならない技術
- 注意点
- DOMを使い回すので、DOMを直接いじるとその状態が残ってしまう
- DOM上の index ≠ データ上の index
なのでindexに依存した処理に注意
最近よく聞く話 - 続き
最近よく聞く話 - 続き
- Flash や Silverlight で作られたアプリをHTML5 ベースに移行したい
- でも...
- パフォーマンスは同程度で
- UI も現行どおりで
- IE11で
- IG:さすがにそれはムリー
たとえばこんなの...
1000
50行x20列
いくら igx-grid でも
- Viewport 部分のみに仮想化しているとはいえ、Viewport 内のセル数が 1000 もあれば、レンダリングコストは計り知れない
- モダンブラウザであれば問題なく使えるが、さすがに IE11 ではパフォーマンス出ない。Flash や Silverlight ではないので。。
UIベンダーとして
- IE11 はもう使うのやめましょうと啓蒙
- モダンブラウザに比べてセキュリティリスクが高い
- ブラウザシェアの減衰(現状10%)
- MS は Edge を使ってほしいと言ってる
UIベンダーとして
- そもそもパフォーマンスの出ない UI にならないよう提案
- Viewport 内のセル数をもっと減らす
- 減らせば、IE11でも十分に使えるレベル
-
俯瞰性の代わりに検索容易性で代替する
- フィルター、検索機能などで簡単に絞り込めるように
- Viewport 内のセル数をもっと減らす
IE11と戦わないように
- 技術的アプローチだけがパフォーマンス改善の方法ではない
-
まずはIE11を使わなくて済むように働きかける(一番大事!)
- 成功すれば、パフォーマンスに限らずいろいろな問題が一気に解決するはず!
IE11と戦わざるを得ない人へ
- IE11 はレンダリングエンジンが弱いので、DOMの描画を最小限にすることが重要
- なるべくDOM数の少ない UI に変更できないか検討する
- 現行通りの UI ではパフォーマンスが出ないことを逆手に取る
- 成功すれば、だいぶ楽になれる!
IE11と戦わざるを得ない人へ
- Angular の場合、Change Detection が無用に走ってしまわないようChangeDetectionStrategy.OnPush を使う
- その分更新タイミングを自分でコントロールしなくてはならないが、パフォーマンスを上げようと思うならば致し方なし。
- scroll, mousemove など大量発生イベントにも気をつける必要あり
- runOutsideAngular 内で実行して Change Detection が走らないようにする
- 人が知覚できないような間隔で発生したイベントは throttling (間引き)することでDOMの更新頻度を減らす
IE11と戦わざるを得ない人へ
まとめ
まとめ
- IE11 は使わないのが最善
- DOM 数を抑えた UI にするのが次善
- UI仮想化(cdkVirtualFor, igxFor)を使ってレンダリングを高速化
- Angular の Change Detection と仲良くする
-
- DetectionStrategy.OnPush
- runOutsideAngular
- 大量発生イベントの throttling
APPENDIX
APPENDIX
- Ignite UI for Angular GitHub
- https://github.com/IgniteUI/igniteui-angular
- オンラインデモ
- https://jp.infragistics.com/products/ignite-ui-angular/angular/components/grid.html
Angular 製高機能グリッドのパフォーマンス問題に立ち向かっている話
By Tatsushi Kiryu
Angular 製高機能グリッドのパフォーマンス問題に立ち向かっている話
- 4,150