DEV mode change detection - Show warning if object reference changes in subsequent check #27804
Labels
area: core
Issues related to the framework runtime
core: change detection
core: debug tools
feature: under consideration
Feature request for which voting has completed and the request is now under consideration
feature
Issue that requests a new feature
Projects
Milestone
馃殌 feature request
Relevant Package
This feature request is for
@angular/core
Description
When Angular does change detection, it will re-render the view whenever a property binding changes. There is a slight issue with what Angular considers a "change". If an object reference changes to an object identical to the first one, Angular will update the view with this new object, even if the view ends up being identical to the previous one. This situation is easy for new developers to fall into, as it very easy to write a function like:
and then bind it to an
[ngClass]
directive, which will remove and re-apply thered
class every change detection call, becausedivClasses()
returns a new object every time it is run.This causes two big problems, the first being inefficient view rendering. Change detection only needs to update the view whenever the component's
isRed
value changes, but it ends up updating the view every single time change detection is run. This would slow down the page and negatively impact the end user's experience.The less obvious problem is the possibility of change detection recursion. If the application has a
MutationObserver
somewhere, watching for DOM changes, the above function will cause it to run every time change detection is ran. If thisMutationObserver
also triggers a change detection check, the page will hang as thedivClasses()
function updates the view, triggering theMutationObserver
, which triggers change detection again. This might not even directly be the developer's fault, as theMutationObserver
could be from a 3rd party library.I recently spent a day and a half attempting to debug an application hanging in this way. Funnily enough, the problem was made worse by a 3rd party library which modified
console.log
to run change detection - which caused recursion to happen again. Ultimately, I suspect this scenario might be the cause of issues like valor-software/ngx-bootstrap#3047, #20450, or #24614.Describe the solution you'd like
To be clear, my proposed "fix" does NOT involve modifying Angular's change detection to deeply compare object references. Discussion on this bug: #24614 was ultimately tabled because the proposed fix involved deep equality checks, which would be inefficient and very time consuming to check larger objects.
Ultimately, the issue here seems to be with functions like my example
divClasses()
, which inadvertently abuse change detection to unnecessarily update the view. If there was some way to alert the developer that a function they've written was possibly faulty, that would probably be the way to go.Currently, Angular displays warnings for change detection when the application is running in dev mode for a similar scenario. If change detection itself causes a property/function to change its output, Angular currently displays a warning about what happened. Could it be possible to display a similar warning for whenever a function returns a different object reference on subsequent change detection calls? A reference check would not be very expensive, and this may end up helping the application developer optimize their program.
The text was updated successfully, but these errors were encountered: