Understanding Angular Ivy: Incremental DOM and Virtual DOM

Original author: Victor Savkin
  • Transfer

Angular is our primary tool for writing a TestMace application . In one of the previous articles, we touched on the topic of Ivy renderer. It's time to learn more about how Ivy differs from the previous engine.




At Nrwl, we have been awaiting for some time the opportunities that Ivy will offer us and our customers. Angular Ivy is the new Angular rendering engine, radically different from all the similar technologies of popular frameworks in that it uses the Incremental DOM.


What is Incremental DOM and how is it different from Virtual DOM?


Let's conduct a comparative analysis and find out why the Incremental DOM is the right solution for Angular.


How Virtual DOM Works


React is a fairly common framework that used Virtual DOM for the first time. The basic idea is this:
Each component creates a new VDOM tree whenever it is rendered. React compares the new tree with the previous one, after which it makes a set of changes to the browser DOM to bring it into line with the new VDOM tree.



Virtual DOM has two main advantages:


  • The ability to use any programming language to implement the component rendering function and the lack of compilation. React developers mostly write in JSX, but regular JavaScript is fine.
  • As a result of component rendering, we get a value that can come in handy when testing, debugging, etc.

Incremental dom


The Incremental DOM is used by Google for internal needs. His main idea is this:


Each component is compiled into a set of instructions that create DOM trees and directly update them when data changes.
For example, this component:


todos.component.ts
@Component({
  selector: 'todos-cmp',
  template: `
    
{{t.description}}
` }) class TodosComponent { todos: Observable = this.store.pipe(select('todos')); constructor(private store: Store) {} }

It will be compiled to:


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;
}());

The template function contains instructions for rendering and updating the DOM. Please note that the instructions are not interpreted by the framework rendering engine. They are the rendering engine.


Benefits of Incremental DOM


Why did Google decide to opt for the Incremental DOM, and not the Virtual DOM?


The task they set is to make applications show good performance on mobile devices. So, it was necessary to optimize the size of the bundle and the amount of memory consumed.


To solve the above tasks:


  • The rendering engine must be tree-shakable
  • The rendering engine should not consume a lot of memory

Incremental DOM and tree shakability


When using incremental DOM, the framework does not interpret the component; instead, the component refers to instructions. If any instruction is left untouched, then it will not be used in the future. Since this information is known at compile time, you can exclude unused instructions from the bundle.



Virtual DOM requires an interpreter to work. At the time of compilation, it is not known which part of it is needed and which part is not, so it is necessary to drive it into the browser entirely.



Incremental DOM and memory consumption


Virtual DOM creates an entire tree from scratch with every re-rendering.



The Incremental DOM does not require memory to re-render the view if it does not make changes to the DOM. The memory will need to be allocated only if DOM nodes are added or deleted, and the amount of allocated memory will be proportional to the changes made to the DOM.



Since most calls to render / template do not make any changes (or the changes they make are minor), significant memory savings are achieved.


Incremental DOM won?


Of course, everything is not so simple. For example, the fact that a render function returns a value provides excellent capabilities, say, in testing. On the other hand, step-by-step instruction execution with Firefox DevTools simplifies performance debugging and profiling. The ergonomics of a particular method depends on the framework used and the preferences of the developer.


Ivy + Incremental DOM =?


Angular has always been built on the use of HTML and templates (a couple of years ago I published a post in which I outlined my thoughts in support of this solution and its long-term effectiveness). That is why the main trump card Virtual DOM will never be a winner for Angular.


With all of this, tree shakability, and low memory consumption, I find it prudent to use the Incremental DOM as the basis for the new rendering engine.



If you need Angular advice, training or support information, you can read about our customer service methods here



Also popular now: