AfterRenderEffect
Angular 19

Doron Azulay
Lifecycle hooks
- OnInit
- OnDestroy
- DoCheck
- OnChanges
- AfterContentInit
- AfterContentChecked
- AfterViewInit
- AfterViewChecked
Constructor / OnInit
Components should be cheap and safe to constructor.
You should not, for example - fetch data in component constructor.
ngOnInit() is a better place for a component to fetch initial data.
@Component({/*...*/})
Class UserComponent {
name = input<string>();
constructor(): {
//inputs aren't set yet
}
ngOnInit(): void {
//can read inputs
}
}OnInit Replacements
- Computed()
- LinkedSignal()
- Resource()
- Effect()
- toObservable() - Effect under the hood
OnDestroy
Use DestroyRef
export class DemoTakeUntilComponent {
private destroyRef = inject(DestroyRef);
// example 1
constructor() {
interval(1000)
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((value) => console.log('Tick:', value));
}
// example 2
const unregisterFn = destroyRef.onDestroy(() => doSomethingOnDestroy());
unregisterFn();
}@Component( ... )
export class FooComponent {
constructor() {
effect(() => { ... })
}
}
Registers an "effect" that will be scheduled & executed whenever the signals that it reads changes.
Use effect()
OnChanges
@Component( ... )
export class FooComponent {
chart = viewChild(MyChart);
constructor() {
afterNextRender(() => {
initChart(...)
})
}
}Run just once!
Replaces:
AfterContentInit,
AfterViewInit
@Component( ... )
export class FooComponent {
chart = viewChild(MyChart);
constructor() {
afterRender(() => {
initChart(...)
})
}
}Run every CD cycle
Replaces:
AfterContentCheck
AfterViewCheck
AfterContentInit / AfterContentChecked
Use afterNextRender / afterRender
AfterViewInit / AfterViewChecked
Use afterRenderEffect()
@Component( ... )
export class FooComponent {
constructor() {
afterRenderEffect({
earlyRead: () => {...},
read: () => {...},
mixedReadWrite: () => {...}
write: () => {...}
});
}
}
Live Coding
AfterRenderEffect
Post-Render Reactivity in Angular
- Precise timing after Angular finishes rendering.
- Perfect for DOM measurements, animations, and 3rd-party orchestration.
- Browser only (no SSR).
- Values propagate between phases as signals.

Phased Execution
Prefer read/wite over earlyRead/mixedReadWrite
| Phase | Rule |
|---|---|
| earlyRead | Read from DOM. Never write here. |
| write | Write to DOM. Never read here. |
| mixedReadWrite | Read + write (use sparingly). |
| read | Final DOM reads after writes. |
| Lifecycle Hook | Replacement |
|---|---|
| ngOnInit | effect() |
| ngOnChanges | effect() |
| ngAfterViewInit | afterRenderEffect() |
| ngAfterViewChecked | afterRenderEffect() |
afterRenderEffect({
earlyRead: () => X,
write: (xSignal) => Y,
mixedReadWrite: (ySignal) => Z},
read: (zSignal) => {...}
});Selective Re-Execution
- Phases run once initially.
- Re-run only when signal dependencies change (dirty).
- Dependencies can come from: previous-phase signals or component signals.
- If the value is identical to the previous run, the next phase won’t execute again.
effect() vs afterRenderEffect()
| Aspect | effect() | afterRenderEffect() |
|---|---|---|
| Purpose | General reactive state | Post-render DOM operations |
| Timing | During change detection | After rendering finishes |
| Use Cases | Signal/data reactions | Measurements, animations, 3rd‑party libs |
| Execution | Re-runs on signal change | Phased; reruns when “dirty” |
| SSR | Supported | Browser only |
| Lifecycle analog | OnInit/OnChanges | AfterViewInit/AfterViewChecked |
When to use
- Use effect() — for most logic reacting to signals or state.
- Use afterRenderEffect() — rarely, only for low-level DOM tasks or library integrations.
It's similar in importance to ngAfterViewInit — powerful but not for everyday code.
AfterRenderEffect
By Doron Azulay
AfterRenderEffect
- 8