Angular 製高機能グリッドのパフォーマンス問題に立ち向かっている話

2018/11/25 Sun

HTML5 Conference 2018

@TatsushiKiryu

About me

Tatsushi Kiryu

Front End Engineer

Infragistics Japan

    Technical Consulting Engineer

Social

最近よく聞く話

最近よく聞く話

  • 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でも十分に使えるレベル
    • 俯瞰性の代わりに検索容易性で代替する
      • フィルター、検索機能などで簡単に絞り込めるように

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