Performance: Directive execution and DOM manipulation
This affects how fast the page renders and responds by controlling when and how DOM elements are created or changed.
import { Directive, ElementRef, Renderer2, AfterViewInit } from '@angular/core'; @Directive({ selector: '[goodDomManip]' }) export class GoodDomManipDirective implements AfterViewInit { constructor(private el: ElementRef, private renderer: Renderer2) {} ngAfterViewInit() { const fragment = document.createDocumentFragment(); for (let i = 0; i < 1000; i++) { const div = this.renderer.createElement('div'); this.renderer.setProperty(div, 'textContent', `Item ${i}`); fragment.appendChild(div); } this.el.nativeElement.appendChild(fragment); } }
import { Directive, ElementRef } from '@angular/core'; @Directive({ selector: '[badDomManip]' }) export class BadDomManipDirective { constructor(private el: ElementRef) { for (let i = 0; i < 1000; i++) { const div = document.createElement('div'); div.textContent = `Item ${i}`; this.el.nativeElement.appendChild(div); } } }
| Pattern | DOM Operations | Reflows | Paint Cost | Verdict |
|---|---|---|---|---|
| Direct DOM append in constructor | 1000 nodes appended individually | 1000 reflows | High paint cost | [X] Bad |
| Batch DOM append with DocumentFragment in ngAfterViewInit | 1000 nodes appended once | 1 reflow | Low paint cost | [OK] Good |
Renderer2 in a directive's constructor?import { Directive, HostListener, Renderer2, ElementRef } from '@angular/core';
@Directive({ selector: '[appHighlight]' })
export class HighlightDirective {
constructor(private el: ElementRef, private renderer: Renderer2) {}
@HostListener('click') onClick() {
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', 'yellow');
}
}import { Directive, ElementRef, Renderer2 } from '@angular/core';
@Directive({ selector: '[appColor]' })
export class ColorDirective {
constructor(el: ElementRef, renderer: Renderer2) {
renderer.setStyle(el.nativeElement, 'color', 'blue');
}
}active on the host element when the user hovers over it, and removes it when the mouse leaves. Which approach correctly implements this behavior?Pass the test and this pattern moves unknown