Angular Ivyの理解:増分DOMと仮想DOM

Angularは、 TestMaceアプリケーションを作成するための主要なツールです。 以前の記事の1つで、 Ivyレンダラーのトピックに触れました。 今度は、Ivyが以前のエンジンとどのように異なるかについて詳しく学びます。



















Nrwlでは、 Ivyが私たちとお客様に提供する機会をしばらく待っていました。 Angular Ivyは新しいAngularレンダリングエンジンであり、Incremental DOMを使用するという点で、一般的なフレームワークのすべての類似技術とは根本的に異なります。







Incremental DOMとは何ですか?Virtual DOMとはどう違いますか?







比較分析を行って、Incremental DOMがAngularの正しいソリューションである理由を見つけましょう。







仮想DOMの仕組み



Reactは、Virtual DOMを初めて使用したかなり一般的なフレームワークです。 基本的な考え方は次のとおりです。

各コンポーネントは、レンダリングされるたびに新しいVDOMツリーを作成します。 Reactは新しいツリーを前のツリーと比較し、その後ブラウザーDOMに一連の変更を加えて、新しいVDOMツリーに合わせます。













仮想DOMには2つの主な利点があります。









増分dom



Incremental DOMは、内部のニーズのためにGoogleによって使用されます。 彼の主なアイデアはこれです:







各コンポーネントは、DOMツリーを作成し、データが変更されたときに直接更新する一連の命令にコンパイルされます。

たとえば、このコンポーネント:







todos.component.ts
@Component({ selector: 'todos-cmp', template: ` <div *ngFor="let t of todos|async"> {{t.description}} </div> ` }) class TodosComponent { todos: Observable<Todo[]> = this.store.pipe(select('todos')); constructor(private store: Store<AppState>) {} }
      
      





次のようにコンパイルされます。







todos.component.js
 var TodosComponent = /** @class */ (function () { function TodosComponent(store) { this.store = store; this.todos = this.store.pipe(select('todos')); } TodosComponent.ngComponentDef = defineComponent({ type: TodosComponent, selectors: [["todos-cmp"]], factory: function TodosComponent_Factory(t) { return new (t || TodosComponent)(directiveInject(Store)); }, consts: 2, vars: 3, template: function TodosComponent_Template(rf, ctx) { if (rf & 1) { // create dom pipe(1, "async"); template(0, TodosComponent_div_Template_0, 2, 1, null, _c0); } if (rf & 2) { // update dom elementProperty(0, "ngForOf", bind(pipeBind1(1, 1, ctx.todos))); } }, encapsulation: 2 }); return TodosComponent; }());
      
      





テンプレート関数には、DOMをレンダリングおよび更新するための指示が含まれています。 指示はフレームワークレンダリングエンジンによって解釈されないことに注意してください。 それらはレンダリングエンジンです。







増分DOMの利点



Googleが仮想DOMではなく、増分DOMを選択することにしたのはなぜですか?







彼らが設定するタスクは、モバイルデバイスでアプリケーションに良好なパフォーマンスを表示させることです。 そのため、バンドルのサイズと消費されるメモリの量を最適化する必要がありました。







上記のタスクを解決するには:









増分DOMおよびツリーシェーカビリティ



インクリメンタルDOMを使用する場合、フレームワークはコンポーネントを解釈しません。 代わりに、コンポーネントは指示を参照します。 いずれかの命令が変更されないままになっている場合、その命令は今後使用されません。 この情報はコンパイル時に既知であるため、未使用の命令をバンドルから除外できます。













仮想DOMを使用するには、インタープリターが必要です。 コンパイル時には、どの部分が必要で、どの部分が必要でないかがわからないため、ブラウザに完全に組み込む必要があります。













増分DOMおよびメモリ消費



仮想DOMは、再レンダリングのたびにゼロからツリー全体を作成します。













Incremental DOMは、DOMに変更を加えない限り、ビューを再レンダリングするためのメモリを必要としません。 メモリは、DOMノードが追加または削除された場合にのみ割り当てる必要があり、割り当てられたメモリの量はDOMに加えられた変更に比例します。













レンダリング/テンプレートへのほとんどの呼び出しは変更を加えないため(またはそれらが行う変更はわずかです)、大幅なメモリ節約が達成されます。







増分DOMが勝ちましたか?



もちろん、すべてがそれほど単純ではありません。 たとえば、レンダリング関数が値を返すという事実は、テストなどで優れた機能を提供します。 一方、Firefox DevToolsを使用した段階的な命令実行により、デバッグとプロファイリングのパフォーマンスが簡素化されます。 特定のメソッドの人間工学は、使用されるフレームワークと開発者の好みに依存します。







Ivy + Incremental DOM =?



Angularは常にHTMLとテンプレートの使用に基づいて構築されています(数年前に、このソリューションとその長期的な有効性をサポートするための考えをまとめた投稿を公開しました)。 そのため、Virtual DOMのメイントランプカードがAngularの勝者になることはありません。







これらすべて、ツリーシェーカビリティ、および低メモリ消費により、Incremental DOMを新しいレンダリングエンジンの基盤として使用するのが賢明な選択だと思います。













Angularのアドバイス、トレーニング、またはサポート情報が必要な場合は、 こちらからカスタマーサービスの方法をお読みください。














All Articles