Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Really slow change detection in hybrid Angular app

We have a hybrid AngularJS / Angular 8 app, and we keep constantly running into issues with really slow change detection between components from different versions of the framework. Until now we've only had this problem when using AngularJS components inside Angular components. The common case is having a new Angular 8 form that has some old AngularJS components in it, and with some specific AngularJS components it can take anywhere between ~2 to ~10 seconds for the changes made in the component to propagate to the Angular form and for form validations to run. The UI doesn't hang or anything, it stays responsive, but there just seems to be a varying delay in communications between the different versions of the framework. Other AngularJS components in the same form might work seamlessly. We haven't found out the root cause for it yet, but we have found one reliable workaround; use $timeout(() => $scope.apply()); in the AngularJS component, usually in the $onChanges-listener. This triggers change detection in Angular and removes the delay.

Now we're facing it with an Angular component that is used inside an AngularJS component. We have a new Angular component that essentially wraps an NG Bootstrap datepicker, and after selecting a date in the datepicker, there is a varying delay of several seconds (up to around 10 seconds) before the parent AngularJS form realizes that any changes were made. Angular's upgrade guide mentions that you can use NgZone.run() to manually trigger change detection when using downgradeModule() (which we are), but we haven't found a way to get it working. The documentation doesn't really go into detail how run() should be used, either. We also tried ChangeDetectorRef.detectChanges(), to no avail.

I tried passing the AngularJS parent component's $scope down to the Angular component and using setTimeout(() => $scope.$apply()); in the Angular component after emitting a change event with an EventEmitter, and that did work; the delay was gone. But obviously this is not something we want to use for real.

Any suggestions on how to eliminate the change detection delay between AngularJS / Angular 8 components, either by manually triggering change detection from an Angular component or some other way?

like image 765
Markus Yrjölä Avatar asked Oct 20 '25 13:10

Markus Yrjölä


1 Answers

In the end we didn't find any other solution than the one described in the question: passing the AngularJS $scope as an input parameter to the Angular component and wrapping the event emissions in $scope.$apply(), i.e.

$scope.$apply(() => valueChange.emit(value));

Based on the Angular upgrade guide, this seems to be the only way to get it working when using downgradeModule().

like image 54
Markus Yrjölä Avatar answered Oct 23 '25 02:10

Markus Yrjölä