Skip to content
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

Large bundle size when importing even a single module #3904

Closed
cexbrayat opened this issue Nov 19, 2020 · 7 comments · Fixed by #3914
Closed

Large bundle size when importing even a single module #3904

cexbrayat opened this issue Nov 19, 2020 · 7 comments · Fixed by #3914

Comments

@cexbrayat
Copy link
Contributor

Bug description:

Adding a single ng-bootstrap module (like NgbCollapseModule in my example) leads to a surprisingly large increase of the application bundle size.

It looks like there is something fishy, as importing just this module in our application drags ~80kb of ng-bootstrap, plus 42kb of @angular/forms. I can reproduce with a bare CLI application (with numbers slightly lower).

Link to minimally-working StackBlitz that reproduces the issue:

https://github.com/cexbrayat/collapse-bundle-size

This repo has been created using the latest CLI (11.0.2)

  • 1rst commit: generate the application (branch chore/init)
ng new collapse-bundle-size --defaults

Building this bare application gives:

ng build --prod --source-map
Initial Chunk Files               | Names         |      Size
main.866a4eb66ed1bedd7877.js      | main          | 135.41 kB

The generated sourcemap looks like
Capture d’écran 2020-11-19 à 14 09 31

  • 2nd commit: add ng-bootstrap (branch feat/ngb-module)

Adding ng-bootstrap produces the following results:

ng add @ng-bootstrap/ng-bootstrap
ng build --prod --source-map
Initial Chunk Files               | Names         |      Size
main.cb92446fa68ee2d403ee.js      | main          | 288.59 kB

That's a large increase, but ng add adds the complete NgbModule to the imports, so that may be expected.
Capture d’écran 2020-11-19 à 14 14 37

  • 3rd commit: import just NgbCollapseModule (master)
    Replace the import of NgbModule by NgbCollapseModule leads to the following results:
Initial Chunk Files               | Names         |      Size
main.1617f8bf4ea0ac9824ea.js      | main          | 270.76 kB

Capture d’écran 2020-11-19 à 14 18 43

Note that the size is slightly better but still very large for a module containing a single directive. It still drags in @angular/forms in the application bundle when you would expect it doesn't.

Versions of Angular, ng-bootstrap and Bootstrap:

Angular: 11.0.1

ng-bootstrap: 8.0.0

Bootstrap: 4.5.3

@thecp
Copy link

thecp commented Nov 22, 2020

I am experiencing the same issue only after updating Angular to v11. Same ng-bootstrap version (or other versions) looks fine with Angular v10 but after update to v11 bundle size grows like you described.

@maxokorokov
Copy link
Member

I'm getting the same results when using the library built with #3906.

Importing NgbCollapseModule:

So needs further investigation for sure.

@santam85
Copy link
Contributor

santam85 commented Dec 4, 2020

Interesting information around possible causes here: https://next.angular.io/guide/ivy-compatibility#payload-size-debugging

@devoto13
Copy link
Contributor

devoto13 commented Dec 8, 2020

I did some debugging and it looks like value accessor variables (like here) is one of the things, which retain code. Inlining the mentioned value accessor results in all typeahead code eliminated from the bundle. I'll try to setup a minimal reproduction and report on Angular CLI repo, but I guess another approach may be to inline them in ng-bootstrap sources 🤔

devoto13 added a commit to devoto13/ng-bootstrap that referenced this issue Dec 8, 2020
To fix dead code elimination using Angular 11.

See angular/angular-cli#19572 (comment) for more details. The *inline* option was chosen as ng-bootstrap does not needs to export these accessors and they're only used by a single component. This option appears the simplest to me, it is less likely to regress in the future and should work independently of whether consumer users Angular CLI or custom tooling to build their application. At the cost of slightly worse code readability.

Fixes ng-bootstrap#3904
@devoto13
Copy link
Contributor

devoto13 commented Dec 8, 2020

Inlining value accessors brings size down ~50%, so there is more to it. I'll continue the investigation tomorrow.

UPD There was one more forwardRef().

devoto13 added a commit to devoto13/ng-bootstrap that referenced this issue Dec 8, 2020
To fix dead code elimination in Angular 11.

See angular/angular-cli#19572 (comment) for more details. The *inline* option was chosen as ng-bootstrap does not needs to export these providers and they're only used by a single component. This option appears the simplest to me, it is less likely to regress in the future and should work independently of whether consumer users Angular CLI or custom tooling to build their application. At the cost of slightly worse code readability.

Fixes ng-bootstrap#3904
@maxokorokov
Copy link
Member

@cexbrayat @devoto13 thanks for getting to bottom of the issue, but looks like it was fixed in the CLI 11.0.4angular/angular-cli#19573.

So I'm going to close this one.

@maxokorokov
Copy link
Member

BTW, I confirmed with ng-bootstrap 8.0.0 and cli 11.0.4. Getting same results as with the suggested fix in #3914

maxokorokov pushed a commit that referenced this issue Dec 22, 2020
To fix dead code elimination in Angular 11.

See angular/angular-cli#19572 (comment) for more details. The *inline* option was chosen as ng-bootstrap does not needs to export these providers and they're only used by a single component. This option appears the simplest to me, it is less likely to regress in the future and should work independently of whether consumer users Angular CLI or custom tooling to build their application. At the cost of slightly worse code readability.

Fixes #3904
santam85 pushed a commit to santam85/ng-bootstrap that referenced this issue Dec 28, 2020
To fix dead code elimination in Angular 11.

See angular/angular-cli#19572 (comment) for more details. The *inline* option was chosen as ng-bootstrap does not needs to export these providers and they're only used by a single component. This option appears the simplest to me, it is less likely to regress in the future and should work independently of whether consumer users Angular CLI or custom tooling to build their application. At the cost of slightly worse code readability.

Fixes ng-bootstrap#3904
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants