Skip to content

Enabling Ivy increases bundle size #16989

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 task done
ghost opened this issue Feb 16, 2020 · 3 comments
Closed
1 task done

Enabling Ivy increases bundle size #16989

ghost opened this issue Feb 16, 2020 · 3 comments
Labels
needs: investigation Requires some digging to determine if action is needed severity4: memory/performance

Comments

@ghost
Copy link

ghost commented Feb 16, 2020

🐞 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.

@sacgrover
Copy link
Contributor

Similar issue is already opened https://github.com/angular/angular-cli/issues/16866

@alan-agius4 alan-agius4 added needs: investigation Requires some digging to determine if action is needed severity4: memory/performance labels Feb 18, 2020
@kyliau
Copy link
Contributor

kyliau commented May 29, 2020

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.

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jun 29, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
needs: investigation Requires some digging to determine if action is needed severity4: memory/performance
Projects
None yet
Development

No branches or pull requests

3 participants