Skip to content

[BREAKING CHANGE] BrowserAnimationsModule makes removal of non-animated elements asynchronous #19094

@youdz

Description

@youdz

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

Currently, importing the BrowserAnimationsModule in in an app makes the removal of all embedded views asynchronous, even if they are not animated. One of the main problems is that it happens even if the module declaring them does not import the BrowserAnimationsModule, just the app importing it seems to override the Renderer for everyone.
It also produces strange situations since addition is also synchronous: with a simple *ngFor, when updating the array given to it, any code happening AfterViewChecked can see both the newly added items and the removed ones lingering around.

Expected behavior

Removal should become asynchronous only if animated elements are found inside of the removed component (including itself). If this is not possible, at the very least offer a solution to force synchronous removal. I tried using @.disabled, but the removal is still asynchronous. Maybe force synchronicity only when @.disabled is used? That should be the safest solution.

Minimal reproduction of the problem with instructions

  1. Here is an example of the behavior I was mentioning for *ngFor: https://plnkr.co/edit/vEBwyVgQdjaAPZmjrGG4?p=preview
    If you open the console, you will see that changing the items from [1, 2, 3, 4, 5] to [4, 5, 6] prints 1 2 3 4 5 6 in ngAfterViewChecked().
    Here is the exact same plunker without the BrowserAnimationsModule import: https://plnkr.co/edit/kb8RGLkLBtPx7SR6nFRj?p=preview
    This time, ngAfterViewChecked() prints 4 5 6 as expected.
  2. Here is an example showing that this is an issue even if doing some kind of "manual" *ngFor (with a naive implementation for the sake of clarity) in a module that does not import BrowserAnimationsModule: https://plnkr.co/edit/kEzzULZHJpusciWSbQix?p=preview
    Once again, if you open the console, you'll see that additions happen immediately, but removals happen asynchronously. It still logs the removed items after removing them.
    If you try removing the BrowserAnimationsModule import from the app, you'll see removal becomes synchronous again.

What is the motivation / use case for changing the behavior?

Some components need the DOM to be updated after view modifications, typically to access their dynamic height or width for rendering purposes. Wrapping all these in setTimeout() affects performance negatively, and is sometime not possible when the view modifications happen in a loop and the DOM needs to be updated at each step.

Environment


Angular version: 4.3.6


Browser:
- All
 
Others:

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: animationslegacy animations package only. Otherwise use area: core.regressionIndicates than the issue relates to something that worked in a previous version

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions