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

bug: Ionic standalone components are not treeshakable #28483

Closed
3 tasks done
hakimio opened this issue Nov 7, 2023 · 2 comments
Closed
3 tasks done

bug: Ionic standalone components are not treeshakable #28483

hakimio opened this issue Nov 7, 2023 · 2 comments
Labels

Comments

@hakimio
Copy link

hakimio commented Nov 7, 2023

Prerequisites

Ionic Framework Version

v7.x

Current Behavior

Ionic standalone components are not treeshakable.

Expected Behavior

Ionic standalone components are treeshakable.

Steps to Reproduce

  1. Clone ionic-treeshaking-test repo
  2. Build the project and check the resulting "Initial Total"
  3. Optionally switch from esbuild to webpack bundler and check the build size again
  4. Change git branch to ionic-module and build the project again
  5. Compare build sizes you get in previous steps

Code Reproduction URL

https://github.com/hakimio/ionic-treeshaking-test

Ionic Info

Ionic:

   Ionic CLI                     : 7.1.1
   Ionic Framework               : @ionic/angular 7.5.3
   @angular-devkit/build-angular : 17.0.0-rc.4
   @angular-devkit/schematics    : 16.2.9
   @angular/cli                  : 17.0.0-rc.4
   @ionic/angular-toolkit        : 10.0.0

Capacitor:

   Capacitor CLI      : 5.5.1
   @capacitor/android : not installed
   @capacitor/core    : 5.5.1
   @capacitor/ios     : not installed

Utility:

   cordova-res : 0.15.3
   native-run  : 1.7.4

System:

   NodeJS : v18.17.1
   npm    : 10.2.3
   OS     : Windows 10

Build sizes

Webpack + Ionic Module

Initial Chunk Files                   | Names                              |  Raw Size | Estimated Transfer Size
main.a536c9608db8fe42.js              | main                               | 438.12 kB |               112.26 kB
polyfills.53dd1ba240d556a9.js         | polyfills                          |  33.09 kB |                10.68 kB
styles.12498b9a067190a0.css           | styles                             |  26.31 kB |                 4.14 kB
runtime.70fad7281072f3ce.js           | runtime                            |   4.50 kB |                 2.17 kB

                                      | Initial Total                      | 502.02 kB |               129.25 kB

esbuild + Ionic Standalone components

Initial Chunk Files   | Names                |   Raw Size | Estimated Transfer Size
chunk-QON5UNTZ.js     | -                    |    1.24 MB |               185.56 kB
polyfills-FCOTMFN3.js | polyfills            |   32.81 kB |                10.63 kB
chunk-HCAOIOEU.js     | -                    |   32.75 kB |                10.89 kB
styles-EBGUPLIJ.css   | styles               |   26.83 kB |                 4.14 kB
main-LNWMOTZP.js      | main                 |   17.68 kB |                 5.11 kB
chunk-W37MDJIX.js     | -                    |   11.04 kB |                 3.95 kB
chunk-ARD6CFHF.js     | -                    |    9.94 kB |                 2.56 kB
chunk-Z4V4M3ZT.js     | -                    |    5.69 kB |                 2.09 kB
chunk-ARLVSRXN.js     | -                    |    3.98 kB |                 1.48 kB
chunk-WQAL34I6.js     | -                    |    1.67 kB |               661 bytes
chunk-ZDO5NYW7.js     | -                    |    1.05 kB |               530 bytes
chunk-QPVVTFFW.js     | -                    | 1022 bytes |              1022 bytes
chunk-WFGC6I42.js     | -                    |  941 bytes |               941 bytes
chunk-7KGURMOZ.js     | -                    |  908 bytes |               908 bytes
chunk-FQ65QLOX.js     | -                    |  762 bytes |               762 bytes
chunk-A73CKFRS.js     | -                    |  686 bytes |               686 bytes
chunk-J6ICYO4L.js     | -                    |  557 bytes |               557 bytes
chunk-4U6PRYVA.js     | -                    |  126 bytes |               126 bytes
chunk-LF5XB4YN.js     | -                    |   99 bytes |                99 bytes

                      | Initial Total        |    1.39 MB |               232.57 kB

Webpack + Ionic Standalone components

Initial Chunk Files           | Names                              |  Raw Size | Estimated Transfer Size
main.fdf3206ac410ddc6.js      | main                               | 743.21 kB |               143.91 kB
polyfills.f8bea4ae787ca74b.js | polyfills                          |  33.09 kB |                10.67 kB
styles.12498b9a067190a0.css   | styles                             |  26.31 kB |                 4.14 kB
runtime.600e94669b643e4d.js   | runtime                            |   2.88 kB |                 1.38 kB

                              | Initial Total                      | 805.49 kB |               160.10 kB
@ionitron-bot ionitron-bot bot added the triage label Nov 7, 2023
@liamdebeasi liamdebeasi self-assigned this Nov 7, 2023
@liamdebeasi
Copy link
Contributor

liamdebeasi commented Nov 7, 2023

Thanks for following up here. I can reproduce the reported behavior with Webpack, but Ionic is working correctly here. I used https://www.npmjs.com/package/source-map-explorer to determine which components are being pulled into your build, and all of the components included are being used in your application. I did not identify any components being pulled into your build that were not being used in your application:

image

The Webpack + Ionic Module test you conducted is incomplete because it does not account for the lazy chunks that are pulled into the build, only the initial chunks. If you include the lazy chunks you'll see that the IonicModule bundle size is much larger than the Webpack + Standalone bundle size. I used the blank starter app in the example below, but the same concepts apply to your application:

Standalone

Initial Chunk Files           | Names             |  Raw Size | Estimated Transfer Size
main.d5594a2760623012.js      | main              | 332.45 kB |                91.19 kB
polyfills.06c05adc04920097.js | polyfills         |  33.16 kB |                10.72 kB
styles.5e14a4afeec93aa2.css   | styles            |  26.21 kB |                 4.10 kB
runtime.36a8f2b7985de7ae.js   | runtime           |   2.92 kB |                 1.42 kB

                              | Initial Total     | 394.74 kB |               107.42 kB

Lazy Chunk Files              | Names             |  Raw Size | Estimated Transfer Size
594.6110149267714db0.js       | ios-transition-js |  10.20 kB |                 2.62 kB
255.47eca8b531546ebc.js       | input-shims-js    |   4.92 kB |                 1.86 kB
195.f213b6e63d9a44ac.js       | shadow-css-js     |   4.49 kB |                 1.92 kB
595.977adb5f788382f5.js       | index9-js         |   1.87 kB |               823 bytes
957.7b7ceefd2d86cff6.js       | home-home-page    |   1.41 kB |               681 bytes
409.b59827dbdd4bb461.js       | keyboard2-js      |   1.25 kB |               578 bytes
250.d2cca6f4e02c8384.js       | md-transition-js  |   1.04 kB |               485 bytes
236.7408419668ab83a9.js       | swipe-back-js     | 730 bytes |               456 bytes
common.543aad3159122aaf.js    | common            | 591 bytes |               321 bytes
313.2235c013565f5f16.js       | status-tap-js     | 531 bytes |               310 bytes

Module

Initial Chunk Files                   | Names                   |  Raw Size | Estimated Transfer Size
main.4892171a0bb2708c.js              | main                    | 379.88 kB |               101.12 kB
polyfills.441dd4ca9dc0674f.js         | polyfills               |  33.16 kB |                10.70 kB
styles.5e14a4afeec93aa2.css           | styles                  |  26.21 kB |                 4.10 kB
runtime.bc10ee425d3122f5.js           | runtime                 |   4.50 kB |                 2.17 kB

                                      | Initial Total           | 443.75 kB |               118.08 kB

Lazy Chunk Files                      | Names                   |  Raw Size | Estimated Transfer Size
polyfills-core-js.93f56369317b7a8e.js | polyfills-core-js       |  91.83 kB |                27.76 kB
5962.26a36d7c5dd42a5e.js              | -                       |  75.90 kB |                 8.43 kB
7059.a03624e0e25e469e.js              | -                       |  71.91 kB |                12.73 kB
3734.9196f324d7e3fba0.js              | -                       |  53.59 kB |                 5.85 kB
4530.e1fb5e14f312e06e.js              | -                       |  49.42 kB |                 6.01 kB
6754.3d2ddb0f6f26c8d1.js              | -                       |  42.48 kB |                 7.04 kB
5860.d14fe139a7d3b98c.js              | -                       |  39.22 kB |                 8.36 kB
6304.c4731ff30e6c65dc.js              | -                       |  35.92 kB |                 6.12 kB
7666.680482ec20e64832.js              | -                       |  32.23 kB |                 5.85 kB
8577.24c72092346333b6.js              | -                       |  26.90 kB |                 6.59 kB
3672.648d8991401855e9.js              | -                       |  26.66 kB |                 4.83 kB
1372.578a3e182236f09f.js              | -                       |  26.03 kB |                 5.09 kB
3998.716c7df843db5565.js              | -                       |  25.25 kB |                 4.10 kB
8866.e511343070169fd2.js              | -                       |  25.06 kB |                 4.04 kB
7219.7b2a70b9bdb0b926.js              | -                       |  23.97 kB |                 4.72 kB
185.218164636b1ff549.js               | -                       |  23.55 kB |                 5.71 kB
8382.8ec86099873c5d35.js              | -                       |  22.91 kB |                 4.78 kB
4090.565dc53e9b520a9b.js              | -                       |  22.35 kB |                 3.28 kB
4087.c20379f95e7e8a45.js              | -                       |  21.92 kB |                 3.57 kB
4458.2c241c62a0a4995b.js              | -                       |  21.57 kB |                 3.86 kB
9882.7e1c0d280b7dfbf5.js              | -                       |  21.05 kB |                 3.82 kB
8633.42ccdb2b6e502065.js              | -                       |  19.61 kB |                 3.69 kB
5454.a5aa32778c61d1f5.js              | -                       |  19.10 kB |                 1.87 kB
7635.07cd2c377262bead.js              | -                       |  18.98 kB |                 3.11 kB
6642.f758d95cf057640d.js              | -                       |  18.21 kB |                 4.23 kB
polyfills-dom.516ff539260f3e0d.js     | polyfills-dom           |  18.05 kB |                 5.03 kB
common.0f990b8d608def44.js            | common                  |  17.98 kB |                 5.22 kB
9857.58aa1e7e8f55ac26.js              | -                       |  13.54 kB |                 2.74 kB
9302.051d13bc0d62e768.js              | -                       |  12.71 kB |                 4.14 kB
8484.651e9934198892f2.js              | -                       |  11.99 kB |                 2.78 kB
5675.3a91fb4bbe336640.js              | -                       |  11.83 kB |                 3.69 kB
505.f5ba46f0043a691e.js               | -                       |  11.75 kB |                 2.25 kB
4764.08765e46fc281de8.js              | -                       |  11.37 kB |                 3.84 kB
3150.c2d8aac1232799cd.js              | -                       |  10.96 kB |                 2.10 kB
9820.5f14657bd57a2b9c.js              | -                       |  10.83 kB |                 2.10 kB
8594.6e8e4b8ff83f929b.js              | ios-transition-js       |  10.21 kB |                 2.62 kB
3483.db182d404614c76c.js              | -                       |   9.28 kB |                 2.37 kB
1315.77f2bbf7f791d2ff.js              | -                       |   8.54 kB |                 1.32 kB
962.04956d1050772698.js               | ios-transition-js       |   8.14 kB |                 2.93 kB
9992.7e1a149a6074182f.js              | -                       |   7.34 kB |                 2.16 kB
6673.68c644335f5fcd26.js              | -                       |   6.92 kB |                 1.23 kB
9588.d7ad392119829517.js              | -                       |   6.23 kB |                 1.53 kB
433.4777f1a2847ebbed.js               | -                       |   6.09 kB |                 1.78 kB
9352.22f330ce1a3974c2.js              | -                       |   5.63 kB |                 1.34 kB
9793.8c0bea4005404a1e.js              | -                       |   5.49 kB |                 1.24 kB
2975.31d7e507323b30c6.js              | -                       |   5.34 kB |                 1.86 kB
8895.62c48967770c74c4.js              | input-shims-d0c93e5d-js |   4.92 kB |                 1.86 kB
2841.16a9ca4f58ff6b97.js              | -                       |   3.84 kB |                 1.29 kB
3544.4e88410b1a317292.js              | -                       |   3.82 kB |               982 bytes
7465.6f9888d169ed189d.js              | -                       |   3.05 kB |               933 bytes
8058.92bc3c5df214f8f0.js              | index-f0cc4e14-js       |   1.87 kB |               825 bytes
6260.086faa43d8405a90.js              | home-home-module        |   1.76 kB |               751 bytes
1745.eb610c10935535e5.js              | -                       |   1.71 kB |               678 bytes
469.87749c99c5bf436c.js               | -                       |   1.50 kB |               509 bytes
7250.dd7a58df6c68d73e.js              | md-transition-js        |   1.04 kB |               486 bytes
8811.6297ceb2b06f67fc.js              | -                       |   1.00 kB |               572 bytes
9611.4d80f605bc6acb92.js              | status-tap-4e96ecf3-js  | 529 bytes |               323 bytes

In your application, the main.*.js chunk for standalone is indeed larger than the module main.*.js chunk. This is due to a difference in how the components are loaded. With the standalone build, the components you need are directly imported into your application. This approach allows for a smaller bundle size potentially at the expense of a larger initial chunk. With the module build, the components are lazily loaded as needed. This approach allows for a smaller initial chunk at the expense of increasing the entire build size.

Ionic does not control how your application is bundled, but I can confirm that the unused Ionic components are being correctly removed from your application build.

I am going to close this, but let me know if you have any questions.

@liamdebeasi liamdebeasi closed this as not planned Won't fix, can't repro, duplicate, stale Nov 7, 2023
@liamdebeasi liamdebeasi removed their assignment Nov 7, 2023
Copy link

ionitron-bot bot commented Dec 7, 2023

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.

@ionitron-bot ionitron-bot bot locked and limited conversation to collaborators Dec 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants