Angularのレンダリングメカニズムを学ぶときの歩き方

公開:2020/12/11
更新:2020/12/26
5 min読了の目安(約5200字TECH技術記事 4

この記事の目的

Angularのドキュメントは、How to useはそれなりにありますが、conceptsが少ないよなあと昔から思っていました。使い方はわかっても、アーキテクチャーがよくわからないのです。

どんなコンセプトなのか?、背景にある考え方は何なのか?、どんな仕組みになっているのか?などは、ウェブで幅広く探すしかありませんでした。そこで、私がこれまで参考にしてきたもののうち、特にレンダリングメカニズムに関して設計思想や仕組みがわかるものを集めました。なるべく一次情報のものをリストアップしています。

最近はangular.ioのコンテンツも充実してきましたが、設計思想的なものは相変わらず少なかったりします。Angularを使うことではなくて、Angularそのものに興味を持ったときのガイドになればと思います。他にもこれはというものがあったら、ぜひコメントなどで教えてください。

なお、APIやクラス名などの実装詳細については、大半のドキュメントがアウトオブデートなので、ご注意ください。あくまで設計思想や仕組みを学ぶための参考資料群です。

本記事はAngular Advent Calendar 2020の11日目です。今回は経験者向けに参考資料の紹介という体ですが、パートタイムでお手伝いしているビットバンク株式会社 Advent Calendar 2020の21日目では初心者向けにレンダリングメカニズムを噛み砕いて詳細解説する予定です。ご興味ある方はそちらもぜひご覧ください。

レンダリングメカニズムの概要

Angularのレンダリングメカニズムの主要登場人物と関係性を説明します。雑な絵ですみませんが、どんな要素があるかを把握できるようにしています。Angularの特徴として、1.Incremental DOM方式、2.プッシュ型の更新モデル、3.コンパイル必須が挙げられます。

事前工程と実行工程

主に開発時に行う事前工程と、ブラウザで行われる実行工程に分かれます。

  • コンパイラ: ソースコードからビルドファイルを生成する。フレームワークの結合が行われ、htmlもjsコードに変換される。
  • レンダラー: ブラウザがビルドファイルを読み込んだら起動される。仮想ビューを作りDOMを操作する。画面が描画される。
  • Incremental DOM: 実ノードにメタ情報が付与された仮想ノードのツリー。レンダラーによって作られる。

初回ロード時の説明図

更新工程

画面を更新する時の工程です。イベント発生や通信終了をトリガーにして、変更を即時適用するプッシュ型の更新モデルです。

  • Zone: ユーザーの入力や通信の終了をフレームワークに通知する。
  • チェンジディテクション: 更新がトリガーされたら、変更が必要なコンポーネントを検出する。
  • レンダラー: 現状のIncremental DOMを参照して変更を適用する。画面が描画される。
  • Incremental DOM: 仮想DOMとは異なり、基本は元のツリーが書き換えられる。毎回スクラップ&ビルドされる組み込みビューなどの派生系もある。

更新時の説明図

レンダリングメカニズムのコンセプトがわかる

Incremental DOM

  • Angular2以降のベースになっているDOMマネジメント方式。
  • reactなどの他のjsフレームワークと比較して、Angularがどんな特徴なのかがわかりやすい。
  • 主に2つのフォーカスがある。
    1. メモリリソースの節約とガベージ・コレクションの負荷軽減のために、仮想DOMを作るのは最初だけにして、更新は既存のツリーを書き換えるようにする
    2. 仮想DOMでもhtml記法そのままで使えるようにする
  • 実現方法は、物理ノードとメタ情報をミックスしたノードツリーを作る。
    • ツリーのベースを仮想にするか物理(DOM)にするかは実装者の選択になる。
    • Angularは仮想ツリーをベースにしている。DOMノードの参照を保持した仮想ノードでツリーが構築される。
  • コンパイルでhtmlをjsコードに事前生成するアイデアも挙げられている。

Incremental DOMの作者が書いた紹介記事

DI、ChangeDetection、routerといったAngularの中核メカニズムを作ったVictor Savkin氏のブログ

Angular2のレンダリングの基本設計

  • angular.js(v1)から仕切り直すにあたって、ベーシックデザインが記載されているドキュメント。Dart版のドキュメントぽいが、基本設計レベルなのでTypeScriptでも十分に参考になると思う。
    • application layerとrender layerに分割する。仮想ビューで抽象化することで、異なる環境/プラットフォームで動けるようにするということが核。
      1. ブラウザのメインプロセスとwebワーカープロセスを跨いで実行できる
      2. サーバーサイドで実行できる
      3. ネイティブアプリを作れる
      4. ブラウザを使わずにUIテストができる
      5. 低性能やバッテリーセーブモードのデバイス向けなどの最適化しやすくなる
    • 大まかな構成やAPI設計
      • application layerとrender layerに加えて、両者をブリッジするRenderer APIの3つの役割構成
      • 初期描画やビューの更新方法
      • DomRendererとNativeScript rendererを分ける
  • こんなことがやりたいよねーということが挙げられていて、DAY1の資料という感がある。現時点ではやりきれていないことが見受けられることも味わい深い。
  • 一般公開されているが基本的にgoogle社内文書らしく、プロジェクト内での位置付けは不明。

実際に動いている仕組みがわかる

公式ドキュメント

一次情報といえば最初に挙げるべき存在のangular.ioで、設計思想や仕組みに関する章は「Angular Concepts」という章です。内容としては、実際にソースコードやAPIの名称になっている概念についての説明が充実しています。

「Angular Concepts」の章

上記で挙げられている内容をざっと一通り解説しているAngularConnectのセッションもおすすめです。

ivy

概要

  • 現時点で最新となるレンダラーの名称。Angular2になってから3世代目となる。
  • 以前よりも更にincremental DOMのAPIに近づいているので、先にincerementalDOMを把握した方が理解しやすい。
  • 大きくランタイムとコンパイラの2つのモジュールで構成される。
    1. ランタイムは、実行時に仮想ビュー層のツリーを参照して変更適用するものである。
    2. コンパイラは、htmlファイルを解析してjsのコードに変えたり、DIを中心にしたフレームワークの結合を事前に行っておくものである。
  • ivyは、1.コンパイル、2.デプロイ、3.ディペンデンシィの3つの単純化を行っている。その結果、軽量化や高速化に加えて、今までやりづらかったエコシステムへの道を開いている。
    • 実行時に必要なものが少なくなったので、WebComponentでのライブラリ配布や他フレームワークとのジョイントなどへの可能性が増している。
    • テンプレートやコンポーネントを作成するAPIが整備されたので、ツール開発やHigher order componentsなどの可能性が増している。

実装設計

もっと詳細に知りたいときにガイドになるものを挙げる。

  • ランタイムの設計


/angular/packages/core/src/render3/VIEW_DATA.md
  • コンパイラの設計

/angular/packages/compiler/design/architecture.md

Change Detection

  • 初回描画後に、画面の更新が必要になる変更を検知するための仕組み。
  • 更新が発生したら、各コンポーネントでビューにバインドしている状態変数が変化したかを調べる。
  • 更新のトリガーとなるのは主に3つ。これを担うのがzoneである。
    1. イベント - click, submit, ...
    2. XHR - サーバーからデータを取得
    3. タイマー - setTimeout(), setInterval()
  • 描画モデルについて、reactはプル型と言っているが、Angularはプッシュ型が基本となる。変更が発生したら即時画面更新するモデルである。

日本語訳: https://qiita.com/lacolaco/items/523d96ddbfe55c4e6949

Zone

  • プッシュ型の更新トリガーを行うための核になっているもの。
  • フレームワークやテストが非同期処理の終了を即時に把握できるように、終了を伝播するコンテクストを作る。
  • Dartの機能がインスパイアになっている。DartやAngularの実装を元にして、TC-39にプロポーザルが起こされている。
  • そのTC-39のプロポーザル文書が、何を解決しようとするものかや解決策のアイデアを理解しやすい。