Skip to content

Make BrowserAnimationsModule delay-loadable #38982

@johncrim

Description

@johncrim

🚀 feature request

Relevant Package

This feature request is for @angular/platform-browser/animations

Description

To make our app start as quickly as possible, particularly on mobile, I've done a bunch of work to minimize initial bundle size. One of the approaches I'm using is async imports (eg import('../foo/foo.module').then(m => m.FooModule)) shortly after the app is loaded, for logic that isn't absolutely required for initial load + first render.

While we use angular animations extensively (because it's awesome!), we don't need it for first page view (relying on CSS animations for the first few seconds). It is currently not possible to move the BrowserAnimationsModule import to a different module from where BrowserModule is imported - because BrowserAnimationModule exports BrowserModule, and the BrowserModule constructor requires that BrowserModule hasn't been loaded in a parent injector. Also, angular won't start if BrowserModule isn't imported by the root module.

I would like the ability to delay load BrowserAnimationsModule, and I think this would be a useful ability for anyone working to speed initial load.

The easiest repro is to create a new project using ng new --strict --minimal. Next, ng build --prod gives me a main bundle size of 187kB.

If I'm going to use @angular/animations in my app, I am currently required to import BrowserAnimationsModule in the root module:

import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Just doing this increases the main bundle to 258 kB (+71kB or +38%).

Describe the solution you'd like

I'd like to be able to initialize the BrowserAnimationsModule shortly after app load, and have animations work after that point:

await delay(1000); import('@angular/platform-browser/animations').then(m => m.BrowserAnimationsModule );

This will probably require that the BrowserAnimationsModule no longer re-export BrowserModule.

Describe alternatives you've considered

The current required configuration works, it just adds unnecessary size to the initial bundle.

I did try directly importing BROWSER_ANIMATIONS_PROVIDERS (which would get around the BrowserModule re-import check), but I couldn't access them.

Another alternative would be to fork the angular code and try to create a new version of BrowserAnimationsModule that doesn't have these limitations, but I haven't gotten desparate enough for that. We'll see what the Angular team thinks about this proposal.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: animationslegacy animations package only. Otherwise use area: core.featureLabel used to distinguish feature request from other issuesfeature: in backlogFeature request for which voting has completed and is now in the backlogfeature: under considerationFeature request for which voting has completed and the request is now under considerationneeds: discussionIndicates than an issue is an open discussion

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions