Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Deep dive into component / classi-angular-night...

Deep dive into component / classi-angular-night-number-3

Wataru KASAHARA

June 13, 2019
Tweet

More Decks by Wataru KASAHARA

Other Decks in Programming

Transcript

  1. • 笠原 渉 (かさはら わたる)
 
 • Classi 株式会社
 •

    フロントエンドエンジニア
 • Angular 日本ユーザー会 staff
 About me
 @kasaharu
  2. マークアップするだけなら単純だが…
 
 - 条件によって生成 or 破棄
 - Input が与えられたら画面更新
 -

    イベントが発火しても画面更新 … などなど
 Deep dive into component
 コンポーネントの ライフサイクル コンポーネントの変更検知
  3. - ngOnInit : generate component すると書いてあるアレ
 
 - ngOnChanges :

    入力値が変わったときの処理を書くアレ
 
 - ngOnDestroy : Observable の購読完了処理をしたりするアレ
 Component lifecycle

  4. Component lifecycle
 lifecycle method ngOnChanges ngOnInit ngDoCheck ngAfterContentInit ngAfterContentChecked ngAfterViewInit

    ngAfterViewChecked ngOnDestroy - 8 つのメソッドがある
 - この順番で実行される

  5. Component lifecycle
 lifecycle method ngOnChanges ngOnInit ngDoCheck ngAfterContentInit ngAfterContentChecked ngAfterViewInit

    ngAfterViewChecked ngOnDestroy - 初回は ngOnInit より先に呼ばれる
 - Input プロパティが渡されていないと呼ばれない
 - SimpleChanges 型のオブジェクトを引数で受け取 れ、今のプロパティと前のプロパティがわかる
 - firstChange フラグで初回かどうかもわかる
 入力値を使って処理をする場所
  6. Component lifecycle
 lifecycle method ngOnChanges ngOnInit ngDoCheck ngAfterContentInit ngAfterContentChecked ngAfterViewInit

    ngAfterViewChecked ngOnDestroy - コンポーネント生成後に呼ばれる
 - Input プロパティに値がセットされた後に呼ばれる ことが保証されている
 - どんなコンポーネントも 1 回は呼ばれる
 初期化処理をする場所
  7. Component lifecycle
 lifecycle method ngOnChanges ngOnInit ngDoCheck ngAfterContentInit ngAfterContentChecked ngAfterViewInit

    ngAfterViewChecked ngOnDestroy - 変更検知のたびに呼ばれる
 - 変更検知については後述

  8. Component lifecycle
 lifecycle method ngOnChanges ngOnInit ngDoCheck ngAfterContentInit ngAfterContentChecked ngAfterViewInit

    ngAfterViewChecked ngOnDestroy - コンポーネント内の外部のビューに値が反映され た後に呼び出される
 - 呼び出されるのは最初の ngDoCheck の後のみ

  9. Component lifecycle
 lifecycle method ngOnChanges ngOnInit ngDoCheck ngAfterContentInit ngAfterContentChecked ngAfterViewInit

    ngAfterViewChecked ngOnDestroy - コンポーネント内の外部のビューに値が変更され た後に呼び出される
 - 初回は ngAfterContentInit の後に、その後は ngDoCheck の後に呼ばれる

  10. Component lifecycle
 lifecycle method ngOnChanges ngOnInit ngDoCheck ngAfterContentInit ngAfterContentChecked ngAfterViewInit

    ngAfterViewChecked ngOnDestroy - コンポーネント内のビューの値が反映されたあと に呼ばれる
 - ngAfterContentChecked の後に呼ばれる

  11. Component lifecycle
 lifecycle method ngOnChanges ngOnInit ngDoCheck ngAfterContentInit ngAfterContentChecked ngAfterViewInit

    ngAfterViewChecked ngOnDestroy - コンポーネント内のビューの値が変更されたあと に呼ばれる
 - 初回は ngAfterViewInit の後に、その後は ngAfterContentChecked の後に呼ばれる

  12. Component lifecycle
 lifecycle method ngOnChanges ngOnInit ngDoCheck ngAfterContentInit ngAfterContentChecked ngAfterViewInit

    ngAfterViewChecked ngOnDestroy - コンポーネントが破棄されるときに呼ばれる
 - Observable の購読解除などをやる場所

  13. Component lifecycle
 lifecycle method ngOnChanges ngOnInit ngDoCheck ngAfterContentInit ngAfterContentChecked ngAfterViewInit

    ngAfterViewChecked ngOnDestroy 変更検知のたびに呼ばれる
 → ngAfterContentChecked が呼ばれる
 → ngAfterViewChecked が呼ばれる
 → コストが高い
 
 できればここで処理をしない
  14. - 変更検知とは?
 - JS 側で発生したイベントを Angular に伝える仕組み 
 
 -

    誰が伝えているか?
 - Zone.js
 
 - 何を検知する?
 - XHRによる非同期通信、タイマー処理、クリックイベント など 
 変更検知

  15. - フレームレートが 60fps あるとスムーズなアニメーション
 - つまり 1 フレームあたり 16msec しか使えない

    
 - ref. RAIL モデル
 
 - 変更検知のたびに全てのコンポーネントを精査するとパフォーマンスに 悪い
 変更検知

  16. - フレームレートが 60fps あるとスムーズなアニメーション
 - つまり 1 フレームあたり 16msec しか使えない

    
 - ref. RAIL モデル
 
 - 変更検知のたびに全てのコンポーネントを精査するとパフォーマンスに 悪い
 変更検知
 ChangeDetectionStrategy
  17. - ChangeDetectionStrategy
 - 変更検知についての戦略を決める 
 
 - Default
 - CheckAlways

    strategy : 毎回チェックする 
 - OnPush
 - CheckOnce strategy : 1 度だけチェックする 
  → Input が変わらない限りコンポーネントの状態が変化しないと判断
 変更検知

  18. - enableDevTools を設定すると Chrome DevTools で計測できる
 - ng.profiler.timeChangeDetection() 
 


    - 簡単な構成でも 13msec -> 2msec くらいになる
 変更検知

  19. - OnPush を使うためには Input プロパティ以外でコンポーネントの状態 が変わらないように実装する必要がある
 
 - Presentational component

    は基本的に Input プロパティが変更された 場合のみ変更処理を必要とし、その他では変わらないようにしておくと 良い
 
 - Input プロパティが多くなると ngOnChanges の処理が膨らむ可能性が あるので getter などを使って適切に処理をわける
 パフォーマンスを意識したコーディング

  20. - Input ごとに getter を用意することで処理が複雑にならない
 - template でメソッドが呼ばれる → AfterViewChecked

    のたびに処理される 
 - getter に重い処理(配列操作など)があるとパフォーマンスが悪くなる 
 - → setter を使うとよい
 getter

  21. - 該当の Input が変更されると setter が呼ばれる
 - template からは変更検知のたびに getter

    が呼ばれる 
 - 処理自体は setter にあり getter は処理済みの値を返すのみなので影響は少ない 
 setter