Skip to content

Enabling Ivy increases bundle size #16989

Closed

Description

🐞 Bug report

Command (mark with an x)

  • build

Description

Looks like Ivy prevents tree shaking of not referenced components/injectables. It's either a bug, or positive difference in build size can only be seen if application code actually uses all features of all dependencies, which is not realistic.

🔬 Minimal Reproduction

  1. Create a minimal application: ng new --defaults --minimal -S -s -t -g ivy-size
  2. Build with and without ivy to measure bundle sizes of an empty app:
  • With "enableIvy": false: main-es2015 is 125 kB
  • With "enableIvy": true: main-es2015 is 103 kB ✔️
  1. Install package angular2-toaster: npm i angular2-toaster
  2. Import ToasterModule in app.module.ts:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ToasterModule } from 'angular2-toaster';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    ToasterModule.forRoot(),
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
  1. Build with and without ivy again:
  • With "enableIvy": false: main-es2015 is 131 kB (increased by 6 kB)
  • With "enableIvy": true: main-es2015 is 144 kB❌(increased by 41 kB)
  1. Add <toaster-container></toaster-container> to app.component.ts
  2. Build again:
  • With "enableIvy": false: main-es2015 is 146 kB
  • With "enableIvy": true: main-es2015 is 144 kB

Sizes equalized, but now compare the final size with the size of an empty app:

  • build with "enableIvy": false increased by (146-125)=21 kB
  • build with "enableIvy": true increased by (144-103)=41 kB

I tried to make builds with command NG_BUILD_DEBUG_OPTIMIZE=minify ng build --prod and I noticed this difference in builds:
image

[ngSwitch] is used in component [toastComp], which is used by component <toaster-container>. But in <toaster-container>, component [toastComp] will not be displayed unless there's at least one element in array toasts. And to add an element I need to inject service ToasterService, which I do not do in my little app.


Here's my attempt to reproduce the issue without dependencies:

  1. Create a minimal application: ng new --defaults --minimal -S -s -t -g ivy-size
  2. Build with and without ivy to measure bundle sizes of an empty app:
  • With "enableIvy": false: main-es2015 is 125 kB
  • With "enableIvy": true: main-es2015 is 103 kB ✔️
  1. Replace app.module.ts with:
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { Component, NgModule } from '@angular/core';

@Component({
  selector: 'app-root',
  template: '<child-component *ngIf="false"></child-component>',
})
export class AppComponent {}

@Component({
  selector: 'child-component',
  template: '<input ngModel>',
})
export class ChildComponent {}

@NgModule({
  imports: [
    BrowserModule,
    CommonModule,
    FormsModule,
  ],
  declarations: [AppComponent, ChildComponent],
  bootstrap: [AppComponent]
})
export class AppModule {}

Lets build it:

  • With "enableIvy": false: main-es2015 is 158 kB
  • With "enableIvy": true: main-es2015 is 157 kB ❌

the initial positive difference in size is gone.

Lets build with NG_BUILD_DEBUG_OPTIMIZE=minify&&ng build --prod:
By looking at difference in builds I can see that not used features of CommonModule are not removed:
image
image

Same for FormsModule:
image
image

Interestingly, some not referenced classes of @angular/forms are removed: I can find RadioControlValueAccessor but not PatternValidator or NgSelectOption.

🌍 Your Environment

Angular CLI: 9.0.2
Node: 12.13.0
OS: win32 x64

Angular: 9.0.1
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: No

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.900.2
@angular-devkit/build-angular     0.900.2
@angular-devkit/build-optimizer   0.900.2
@angular-devkit/build-webpack     0.900.2
@angular-devkit/core              9.0.2
@angular-devkit/schematics        9.0.2
@angular/cli                      9.0.2
@ngtools/webpack                  9.0.2
@schematics/angular               9.0.2
@schematics/update                0.900.2
rxjs                              6.5.4
typescript                        3.7.5
webpack                           4.41.2

Anything else relevant?
I tried to set "sideEffects": false, in package.json of angular2-toaster, it didn't help.

Activity

  1. sacgrover commented on Feb 17, 2020

    @sacgrover
    Contributor
  2. kyliau commented on May 29, 2020

    @kyliau
    Contributor

    As @sacgrover mentioned, this is a dupe of https://github.com/angular/angular-cli/issues/16866. I'll close this issue in order to consolidate similar issues.

  3. angular-automatic-lock-bot commented on Jun 29, 2020

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  4. locked and limited conversation to collaborators on Jun 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions