关于Angular的渲染机制
首先
我在实际工作中使用Angular大约3年时间,但对于所谓的SPA(单页面应用)作为一个框架如何操作DOM、即屏幕重新绘制的机制并没有理解。
在我进行各种调查时,我遇到了一些陌生的词汇,比如虚拟DOM和节点,进一步调查后,我发现了一篇非常易懂地解释了Angular渲染机制的文章。
Angular的渲染机制的详细解释
作者:田中敏弥先生
我将在这篇文章中简要地总结上述内容作为备忘录。如果您想了解更多详细信息,请参考原始文章。
总结
-
- Angular登場前後のDOMマネジメントの仕組み
-
- AngularのDOMマネジメント
- 描画や更新のメカニズム
Angular登场之前和之后的DOM管理机制
-
- 2010年代前半をピークに、リッチなフロントエンドアプリ(インタラクティブなゲームや規模の大きな業務アプリ)を作る際はDOMをほぼ直接操作することが当たり前だった
HTML要素の多くの属性やイベントを手続き的に管理・操作
jQueryが登場するも、DOM操作のショートハンディングを提供するのみでDOMの手続き的操作のパラダイムを買えるものではなかった
そんな中、DOM操作にデータバインディングを被せてDOMマネジメントを簡易化するEmberやAngular(v1)が登場
更にその後、仮想DOMを提供するReactも登場
Angular(v1)はHTML拡張というアプローチであったが、Reactはall jsのアプローチで、物理的なDOM層を完全に隠蔽した「仮想ビュー層」という新しいレイヤーを追加
仮想ビューはjs空間内で、DOMとは別に画面状態の論理情報を一通り保有する層(DOMはあくまでjs空間に対するAPIであり、状態が格納されているのはレンダリングエンジン側)
これにより、DOM操作を開発者が直接触らずに済むようになる
如果您想了解有关渲染引擎的信息,请点击以下链接:
https://zenn.dev/syommy_program/articles/d868adf9ba3225
换句话说,我们不再需要直接操作DOM了。
Angular的DOM管理
在DOM管理机制方面,Angular利用HTML扩展,而React则具有虚拟视图层的机制。
…那么Angular没有虚拟视图?
事实上,Angular也有虚拟视图层。
只需一种选择:Angular 在版本1和版本2及以后的版本中有着重大的架构变化。
-
- v1
HTML拡張方式で、アドオンによりjs側で追加・拡張していく方式(ディレクティブと呼ぶ)
拡張されたHTMLをブラウザが読み込み、jsが後から動く
v2以降
Reactと同様、js空間にある仮想ビュー層で画面状態の論理情報を管理
AngularはReactと異なりHTMLファイルが存在するが、各々のHTMLファイルはビルド後にjsコードとなる
HTMLファイルとしてブラウザに読み込まれるわけではなく、実行時にjsファイルから画面生成指示が行われており、その点ではReactやVue.jsと同様
那么,Angular也是使用虚拟DOM的方式吗?
→ 从v2开始,采用了改良过的”增量DOM方式”来构建视图层。将此与Angular的特色之一——DI系统相结合,形成了视图层。
对于虚拟DOM而言,IncrementalDOM具有以下两个优点。
1. 增量更新:在进行DOM操作时,IncrementalDOM只更新需要变化的部分,而不是整个DOM树,这样可以减少DOM操作的数量和计算成本。
2. 轻量级:IncrementalDOM是一个轻量级的库,它的代码体积较小,加载和执行速度较快,可以提高应用程序的性能。
-
- メモリリソースの節約とガベージ・コレクションの負荷軽減
仮想DOMを作るのは最初だけで、更新は既存のツリーを書き換えるような仕組み
そのためにリアルDOMと仮想DOMを分けず、リアルノードにメタ情報を追加したバーチャルノードを作成してツリーを作成している
更新時は、このツリーをトラバースして変更するノードを見つける。その仮想ノードはリアルノードの参照を持っているため、リアルDOMを更新することができる
HTML記法をそのまま使える
Angular採用的不是纯粹的IncrementalDOM,而是有很大差别的。
绘画与更新机制的描述和更新机制
Angular的渲染机制具有三个特点。
-
- IncrementalDOM方式
前項で紹介
プッシュ型の更新モデル
描画後の更新モデル。Angularでは何か変更があった際に即時更新するプッシュ型のモデルを採用
コンパイル(トランスパイル)必須
TypeScriptで書くことが必須であることに加え、フレームワークのための解析加工処理も行われる
根据上述特点,构建→绘图→屏幕更新的流程如下所示。
请阅读原文,因为在这里我们将删除类似原始文章的源码解释,但这对您非常有参考价值。
-
- ビルド
Angularは、JIT(Just-in-time)ではなく基本的にはAoT(Ahead-of-time)で、事前に静的解析してビルドファイルを作成しておく
ビルドでは、ただTypeScriptをJavaScriptにトランスパイルしたり最適化しているだけでなく、フレームワークとして実行に必要な加工処理を行う
HTMLファイル→JavaScriptコードの変換、@’Componentや@’Injectableのようなデコレータで記述されているメタデータや、NgModuleとして記述されているコンパイルコンテクストなどの解決など
以下、ビルド方法
HTMLをjsの生成関数に変換する
CSSやアニメーションもjsコードに整理される
コンパイルコンテクストに基づきDIやModuleの解決や結合が行われる
描画
ブラウザがビルドファイルを読み込むと、生成関数が動きソースコードで記述していたテンプレートが画面に描画される
この過程では先述の生成関数が動くだけでなく、DIが核になりさまざまなサービスの注入やその機能が実施される
画面更新
更新する方法
主だった要素作成やイベントリスナーの付与などの重い処理は初回生成時に一度だけ行うようにして、以後は更新用のコードブロックだけが繰り返し実行される
更新するトリガー
変更の発生時
変更検知は「zone.js」というライブラリを使用することで、非同期関数の解決を検知している
上記により、UIイベント(click, submit, …)、サーバーからの通信、タイマー(setTimeout(), setInterval())といった非同期スタックの終了検知を実現
更新する箇所の特定
上記で記載したzone.jsの通知をトリガーとし、画面に描画されているコンポーネントのツリーのどこに変化が起こったどうかを調べるアルゴリズムを実施
この変更検知のアルゴリズムおよび実行モジュールをチェンジ・ディテクション(ChangeDetection)と呼ぶ
これにより変更が起こったと判定されたコンポーネントを洗い出し、そのコンポーネントのテンプレートの更新用関数だけを実行する
最后
对于我这个不了解HTML渲染和DOM机制的人来说,最初介绍的那篇文章非常有帮助。
如果您想更深入地了解DOM和虚拟DOM,以下的文章也是值得推荐的。
-
- 【JavaScriptの基本】DOMの仕組みと構造
-
- 【React】仮想DOMって何!?コンポーネントのレンダリングと描画について理解しよう!
- 仮想DOMは純粋なオーバーヘッド(Virtual DOM is pure overhead)
阅读原文时发现有一篇针对经验丰富者的文章,希望您也一定要读。(摘自原文的“结语”部分)
- Angularのレンダリングメカニズムを学ぶときの歩き方
感谢您一直阅读到最后。