I have a webcomponent that for perf reasons needs to run outside angular.
I came up with the basic idea :
@Component({
selector: 'run-outer-zone',
template: ''
})
class OuterZoneComponent {
constructor(private vcr: ViewContainerRef, private ngZone: NgZone) {
this.ngZone.runOutsideAngular(() => {
const compRef = vcr.createComponent(MyComponentWhichNeedsToRunOutsideAngular);
compRef.data = // set the inputs
})
}
}
It works fine but that's not very generic and it's cumbersome if have multiple web components to handle.
Is it possible to build a custom generic component where the projected content is run in the outer zone ?
I ended up writing my own directive to run specific components outside the NgZone.
It's hugely inspired by how the NgIf
works.
@Directive({
selector: '[runOutside]',
standalone: true,
})
export class RunOutsideDirective<T> {
private isOutside: boolean;
constructor(
private _viewContainer: ViewContainerRef,
private ngZone: NgZone,
private templateRef: TemplateRef<T>
) {}
ngOnInit() {
this.updateView(true);
}
@Input()
set runOutside(doRunOutside) {
this.updateView(doRunOutside);
}
private updateView(doRunOutside: boolean) {
if (doRunOutside === this.isOutside) {
return;
}
this._viewContainer.clear();
if (doRunOutside) {
this.ngZone.runOutsideAngular(() => {
this._viewContainer.createEmbeddedView(this.templateRef);
});
} else {
this._viewContainer.createEmbeddedView(this.templateRef);
}
}
}
usage :
<my-cmp *runOutside></my-cmp>