carbon icon indicating copy to clipboard operation
carbon copied to clipboard

Package performance and bundle-size

Open joshblack opened this issue 6 years ago • 23 comments

In 2020, we want to become more aware and sensitive to the performance of the packages we ship. Overall, this would include focusing on the following areas:

  • The ability to get the overall bundle size of shipped JavaScript and CSS assets for a bundle
  • The ability to track the sizes of files over time
  • The ability to comment on PRs with the reported change in size
  • The ability to test that a package can be tree-shaken / dead-code eliminated

joshblack avatar Dec 15 '19 21:12 joshblack

I think this would be an amazing addition. I've recently noticed that on a simple example of using @carbon/icons-react package (within cra), the bundle was 2.16MB despite only importing a single icon:

image

Looking at the es/index.js, looks like each is labeled as PURE but seems like that's not doing enough.

paul-sachs avatar Feb 10 '20 21:02 paul-sachs

@paul-sachs most like that's related to some kind of webpack configuration issue, if you install and use it from a stock CRA it will get tree-shaken so something is going on in the build and optimization pipeline 🤔

joshblack avatar Feb 10 '20 21:02 joshblack

@joshblack this was a pretty clean cra app (created a few days ago) with some customize-cra to enable less loading along with bundle analyzer. I was surprised as well. Maybe you're right, might be just something weird about my config.

paul-sachs avatar Feb 10 '20 21:02 paul-sachs

@paul-sachs Did you solve that issue?

baeharam avatar May 30 '20 04:05 baeharam

@baeharam check the code for any ".../lib/..." imports that was the case for me

doublepithre avatar May 30 '20 04:05 doublepithre

@doublepithre I use typescript and when I use full import, type cannot be inferred. Any idea?

Could not find a declaration file for module '@carbon/icons-react/es/search/16'. '/Users/haram/haram/github/my-project/node_modules/@carbon/icons-react/es/search/16.js' implicitly has an 'any' type. If the '@carbon/icons-react' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/carbon__icons-react`

baeharam avatar May 30 '20 04:05 baeharam

@baeharam try installing types for this package https://github.com/DefinitelyTyped/DefinitelyTyped/pull/38879 https://www.npmjs.com/package/@types/carbon__icons-react

doublepithre avatar May 30 '20 04:05 doublepithre

@doublepithre I already installed, but when I use full import, it cannot infer type. My stackoverflow question

baeharam avatar May 30 '20 05:05 baeharam

@doublepithre thank you!! this was the same issue I was having, removed the imports and my bundle size has been significantly reduced. 👍

JoshuaTruscott avatar Jul 17 '21 22:07 JoshuaTruscott

@baeharam I filed https://github.com/carbon-design-system/carbon/issues/9540 about the type problems for subpackage imports.

brandones avatar Sep 13 '21 17:09 brandones

I just filed https://github.com/carbon-design-system/carbon/issues/9651 (creating a Babel plugin to transform standard imports into subpackage imports), which I think would do wonders for developer experience, as well as resolve (/moot) the type problems for subpackage imports.

brandones avatar Sep 13 '21 17:09 brandones

Just bumped into this issue really bad. This is a bundle analysis for a Gatsby app. It's not just that tree shaking isn't working, in my case each icon brings a whole bucket of icons with it. Each bucket is 150-175K. This is humongous. I got several MB of icons and many many chunks

image

@doublepithre solution worked brilliantly for me

import ChevronUp24 from '@carbon/icons-react/es/chevron--up/24';

cortopy avatar Feb 16 '22 11:02 cortopy

Hi @cortopy, generally when all of the icons are included there is some part of a project that imports from lib.

Here's a quick way that we test to make sure icons are able to be tree-shaken: https://github.com/carbon-design-system/carbon/issues/6602#issuecomment-729207760

If there are steps to reproduce the issue that you're experiencing, let me know! Happy to take a look and see what's going on.

joshblack avatar Feb 18 '22 16:02 joshblack

Thanks @joshblack . In my case I didn't have any import of lib but changing to long es imports worked. I only had around 10 imports so it was easy for me to do.

The only thing different I had was import type { CarbonIconType } from '@carbon/icons-react'. I wouldn't think that's the issue since it's just a type but don't know if that's the issue

cortopy avatar Feb 24 '22 09:02 cortopy

The ability to get the overall bundle size of shipped JavaScript and CSS assets for a bundle The ability to comment on PRs with the reported change in size

For these two, I like the idea of adding dangerJS and using it to get prod/PR bundle sizes and compare them, then comment on PRs.

React uses this approach. They're using pre-minified bundles though. We'll need to minify ours before compressing with gzip and report on each.

Ideally this would apply for every package in the monorepo, but we could start with just @carbon/react.

I also think compiling @carbon/styles sass to css and tracking that bundle size could be useful as well.

tay1orjones avatar Dec 19 '22 14:12 tay1orjones

The risk of not doing this. We risk bloating the bundle size without knowing about it. Lower-level infrastructure. Test coverage would be a higher priority as an example.

sstrubberg avatar Jan 10 '23 19:01 sstrubberg

Is the effort to reduce the size of packages still on?

Trying to use tools like Bundlephobia to measure... Show build errors: https://bundlephobia.com/package/@carbon/styles

Screenshot 2023-05-17 at 12 10 06 PM

Instead of the bundle size like other packages: https://bundlephobia.com/package/lit

abdonrd avatar May 17 '23 16:05 abdonrd

In our Nuxt project, the top 5 dependencies are:

300M	@carbon
200M	@ibm
 38M	typescript
 34M	@babel
 20M	carbon-components

Using:

"@carbon/icons-vue": "^10.49.1",
"@carbon/styles": "^1.29.0",
"@carbon/web-components": "^1.27.0",
"@ibm/plex": "^6.3.0",
// ...

abdonrd avatar May 19 '23 16:05 abdonrd

Is the effort to reduce the size of packages still on?

Just to clarify, this issue is for beginning to analyze, report, and track bundle size information. It's not an effort to reduce the bundle size (yet).

Once we begin tracking the bundle size(s) and ensuring tree-shaking works on every PR, a workstream could spawn to work on evaluating if and how bundle size could be reduced.

Trying to use tools like Bundlephobia to measure... Show build errors:

I'm not sure why bundlephobia fails to build the package, https://github.com/pastelsky/bundlephobia/issues/795

tay1orjones avatar Dec 13 '23 14:12 tay1orjones

@tay1orjones thanks for the update!

abdonrd avatar Dec 13 '23 14:12 abdonrd

I see it works with other measure tools like pkg-size:

  • https://pkg-size.dev/@carbon%2Fstyles (52MB / 15 packages) Screenshot 2023-12-13 at 9 47 50 AM

  • https://pkg-size.dev/@carbon%2Fweb-components (80MB / 26 packages) Screenshot 2023-12-13 at 9 48 02 AM

  • https://pkg-size.dev/@carbon%2Freact (93MB / 64 packages) Screenshot 2023-12-13 at 9 50 28 AM

  • https://pkg-size.dev/@ibm%2Fplex (186MB / 1 package) Screenshot 2023-12-13 at 9 52 11 AM

abdonrd avatar Dec 13 '23 14:12 abdonrd

With Vite (rollup) I was doing bundle optimisation and experimenting with changing all the paths from the generated files import { IconName } from '@carbon/icons-react' to the /es/IconName import and using the individual imports allows tree-shaking.

I compared 3 different approaches and settled on the vite-plugin way (published here; https://github.com/tablecheck/frontend/tree/main/packages/vite-import-massager-plugin)

  • Default way of just import from '@carbon/icons-react'
  • Changing my code with a vite plugin to transform imports pre-build to '@carbon/icons-react/es/IconName' specific Imports
  • Changing the index.js file in node_modules to import the individual files and not the generated bundle files.
Approach Tree Shaking Build Speed
Default No Normal
Vite Plugin Yes Normal
node_modules Yes Very Slow

Screenshot of carbon icons import in the main bundle.

CleanShot 2024-09-10 at 09 50 05

SimeonC avatar Sep 10 '24 03:09 SimeonC

@SimeonC Last year we had a similar report about the default approach:

  • https://github.com/carbon-design-system/carbon/issues/13865

If you'd like to continue discussing this please open a new issue. This one here is just regarding adding tooling for tracking our own bundle size(s) in PRs and over time.

tay1orjones avatar Sep 13 '24 19:09 tay1orjones