Comprensión de la hiedra angular: DOM incremental y DOM virtual

Angular es nuestra herramienta principal para escribir una aplicación TestMace . En uno de los artículos anteriores, tocamos el tema del renderizador Ivy. Es hora de aprender más sobre cómo Ivy difiere del motor anterior.




En Nrwl, hemos estado esperando durante algún tiempo las oportunidades que Ivy nos ofrecerá a nosotros y a nuestros clientes. Angular Ivy es el nuevo motor de renderizado angular, que es fundamentalmente diferente de todas las tecnologías similares de los marcos populares en el sentido de que utiliza el DOM incremental.


¿Qué es DOM incremental y en qué se diferencia de DOM virtual?


Realicemos un análisis comparativo y descubramos por qué el DOM incremental es la solución correcta para Angular.


Cómo funciona el DOM virtual


React es un marco bastante común que usó Virtual DOM por primera vez. La idea básica es la siguiente:
Cada componente crea un nuevo árbol VDOM cada vez que se representa. Reaccionar compara el nuevo árbol con el anterior, después de lo cual realiza un conjunto de cambios en el DOM del navegador para alinearlo con el nuevo árbol VDOM.



El DOM virtual tiene dos ventajas principales:


  • La capacidad de utilizar cualquier lenguaje de programación para implementar la función de representación del componente y la falta de necesidad de compilación. Los desarrolladores de React escriben principalmente en JSX, pero JavaScript normal está bien.
  • Como resultado de la representación de componentes, obtenemos un valor que puede ser útil al probar, depurar, etc.

Dom incremental


Google utiliza el DOM incremental para necesidades internas. Su idea principal es esta:


Cada componente se compila en un conjunto de instrucciones que crean árboles DOM y los actualizan directamente cuando cambian los datos.
Por ejemplo, este componente:


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>) {} } 

Se compilará para:


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

La función de plantilla contiene instrucciones para representar y actualizar el DOM. Tenga en cuenta que las instrucciones no son interpretadas por el motor de renderizado de framework. Son el motor de renderizado.


Beneficios del DOM incremental


¿Por qué Google decidió optar por el DOM incremental, y no el DOM virtual?


La tarea que establecen es hacer que las aplicaciones muestren un buen rendimiento en dispositivos móviles. Por lo tanto, era necesario optimizar el tamaño del paquete y la cantidad de memoria consumida.


Para resolver las tareas anteriores:


  • El motor de renderizado debe ser movible en árbol
  • El motor de renderizado no debe consumir mucha memoria

DOM incremental y capacidad de intercambio de árboles


Cuando se usa DOM incremental, el marco no interpreta el componente; en cambio, el componente se refiere a instrucciones. Si alguna instrucción se deja intacta, no se usará en el futuro. Dado que esta información se conoce en tiempo de compilación, puede excluir del paquete las instrucciones no utilizadas.



El DOM virtual requiere un intérprete para funcionar. En el momento de la compilación, no se sabe qué parte se necesita y qué parte no se necesita, por lo que es necesario llevarlo completamente al navegador.



DOM incremental y consumo de memoria


Virtual DOM crea un árbol completo desde cero con cada nueva representación.



El DOM incremental no requiere memoria para volver a representar la vista si no realiza cambios en el DOM. La memoria deberá asignarse solo si se agregan o eliminan nodos DOM, y la cantidad de memoria asignada será proporcional a los cambios realizados en el DOM.



Dado que la mayoría de las llamadas a render / template no hacen ningún cambio (o los cambios que hacen son menores), se logran importantes ahorros de memoria.


DOM incremental ganado?


Por supuesto, no todo es tan simple. Por ejemplo, el hecho de que una función de representación devuelva un valor proporciona excelentes capacidades, por ejemplo, en las pruebas. Por otro lado, la ejecución de instrucciones paso a paso con Firefox DevTools simplifica la depuración y la creación de perfiles de rendimiento. La ergonomía de un método en particular depende del marco utilizado y las preferencias del desarrollador.


Ivy + DOM incremental =?


Angular siempre se ha basado en el uso de HTML y plantillas (hace un par de años publiqué una publicación en la que expuse mis pensamientos en apoyo de esta solución y su eficacia a largo plazo). Es por eso que la tarjeta de triunfo principal Virtual DOM nunca será un ganador para Angular.


Con todo esto, la capacidad de intercambio de árboles y el bajo consumo de memoria, me parece prudente usar el DOM incremental como base para el nuevo motor de renderizado.



Si necesita asesoramiento angular, capacitación o información de soporte, puede leer sobre nuestros métodos de servicio al cliente aquí


Source: https://habr.com/ru/post/448048/


All Articles