Performance: @ContentChild and content projection
MEDIUM IMPACT
This concept affects rendering speed and interaction responsiveness by how Angular queries and projects DOM nodes inside components.
import { Component, ContentChild, AfterContentInit, ElementRef } from '@angular/core'; @Component({ selector: 'good-projection', template: `<ng-content></ng-content>` }) export class GoodProjectionComponent implements AfterContentInit { @ContentChild('projectedRef', { static: false }) projectedElement!: ElementRef; ngAfterContentInit() { const el = this.projectedElement.nativeElement; const height = el.offsetHeight; const width = el.offsetWidth; console.log(height, width); } }
import { Component, ContentChild, AfterContentInit, ElementRef } from '@angular/core'; @Component({ selector: 'bad-projection', template: `<ng-content></ng-content>` }) export class BadProjectionComponent implements AfterContentInit { @ContentChild('projectedRef', { static: false }) projectedElement!: ElementRef; ngAfterContentInit() { // Accessing nativeElement multiple times console.log(this.projectedElement.nativeElement.offsetHeight); console.log(this.projectedElement.nativeElement.offsetWidth); } }
| Pattern | DOM Operations | Reflows | Paint Cost | Verdict |
|---|---|---|---|---|
| Multiple nativeElement reads in ngAfterContentInit | Single query, multiple property reads | 2 reflows | Medium paint cost | [X] Bad |
| Single nativeElement read cached in variable | Single query, single property read | 1 reflow | Low paint cost | [OK] Good |
| @ContentChild query in ngAfterContentChecked | Multiple queries per cycle | Multiple reflows | High paint cost | [X] Bad |
| @ContentChild query in ngAfterContentInit only | Single query | 1 reflow | Low paint cost | [OK] Good |