primer / octicons

A scalable set of icons handcrafted with <3 by GitHub
https://primer.style/foundations/icons
MIT License
8.21k stars 828 forks source link

[Bug]: Using styled-octicons in development mode significantly bloats bundle #981

Open pveierland opened 10 months ago

pveierland commented 10 months ago

Describe the bug

Importing a single icon from styled-octicons into my Next.js React application increases the bundle size of the importing component from ~2 MB to ~350 MB in a development build when using the next dev server. When viewing the files distributed as node_modules/@primer/styled-octicons/dist/icons/*, it appears that every icon file includes every icon distributed. In a development build, all N icons are included fully N times, causing an N*N import footprint in the bundle. This causes the developer experience to become very slow and unstable.

Steps to reproduce

Steps to reproduce the behavior:

  1. Use next dev to run a Next development server.
  2. Add import import { CheckboxIcon } from '@primer/styled-octicons'; within React application using Next.js + webpack.

(The same issue appears when using: import * as StyledOcticons from '@primer/styled-octicons';)

image

Expected behavior

When using import { CheckboxIcon } from '@primer/octicons-react'; the size of the resulting webpack component bundle is ~2 MB. It is not expected that the size would be exactly the same, but that the size difference would be less excessive.

In a production build using next build; next export, the issue is resolved as the tree-shaking appears to correctly get rid of unused icons.

image

Device details

Additional info

Version 17.5.0 is listed with an unpacked size of 1.4 MB: https://www.npmjs.com/package/@primer/styled-octicons/v/17.5.0

Version 17.8.0 is listed with an unpacked size of 107 MB: https://www.npmjs.com/package/@primer/styled-octicons/v/17.8.0

pveierland commented 5 months ago

For those using Next.js, the following helps mitigate the issue:

const nextConfig = {
    experimental: {
        optimizePackageImports: [
            '@primer/octicons-react',
            '@primer/styled-octicons'
        ],
    },
};
fregante commented 5 months ago

This is a severe build bug in the @primer/styled-octicons package.

In short, each icon contains the whole library, even if unused.

This is /dist/icons/AccessibilityIcon.js:

Screenshot

You're importing from the index, which internally looks like:

export {AccessibilityIcon.js} from './dist/AccessibilityIcon.js'
// etc repeated N times

So yes, that's why the weight is N*N 😅