base-ui icon indicating copy to clipboard operation
base-ui copied to clipboard

[code-infra] Add bundle size monitor

Open Janpot opened this issue 8 months ago • 6 comments

Porting the bundle size monitor from core. This establishes a baseline. This bundles each entrypoint with its dependencies. Bundles are stored in S3 for comparison. Peer dependencies are ignored. To inspect the created bundles run

pnpm size:why

examples:

Screenshot 2025-05-09 at 10 06 31

Screenshot 2025-05-15 at 15 01 28

Janpot avatar Apr 28 '25 14:04 Janpot

Deploy Preview for base-ui ready!

Name Link
Latest commit f1f2b1f64fb5934287b055689c353336dedcbe73
Latest deploy log https://app.netlify.com/projects/base-ui/deploys/6838276971600b00080e20b6
Deploy Preview https://deploy-preview-1791--base-ui.netlify.app
Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

netlify[bot] avatar Apr 28 '25 14:04 netlify[bot]

Bundle size report

:no_entry_sign: No bundle size snapshot found for base commit 4285f430b031ff47fceb63f9f9a37c1a8de615d1.

Total Size Change: +1.45MB(0.00%) - Total Gzip Change: +491KB(0.00%) Files: 41 total (41 added, 0 removed, 0 changed)

@base-ui-components/reactparsed:${\tiny{\color{orangered}▲}}$+308KB(new) gzip:${\tiny{\color{orangered}▲}}$+92.6KB(new) @base-ui-components/react/menuparsed:${\tiny{\color{orangered}▲}}$+114KB(new) gzip:${\tiny{\color{orangered}▲}}$+37.8KB(new) @base-ui-components/react/context-menuparsed:${\tiny{\color{orangered}▲}}$+113KB(new) gzip:${\tiny{\color{orangered}▲}}$+36.9KB(new) @base-ui-components/react/selectparsed:${\tiny{\color{orangered}▲}}$+111KB(new) gzip:${\tiny{\color{orangered}▲}}$+37.1KB(new) @base-ui-components/react/popoverparsed:${\tiny{\color{orangered}▲}}$+86.1KB(new) gzip:${\tiny{\color{orangered}▲}}$+29KB(new) @base-ui-components/react/navigation-menuparsed:${\tiny{\color{orangered}▲}}$+84.9KB(new) gzip:${\tiny{\color{orangered}▲}}$+28.5KB(new) @base-ui-components/react/tooltipparsed:${\tiny{\color{orangered}▲}}$+63.9KB(new) gzip:${\tiny{\color{orangered}▲}}$+21.6KB(new) @base-ui-components/react/preview-cardparsed:${\tiny{\color{orangered}▲}}$+59.2KB(new) gzip:${\tiny{\color{orangered}▲}}$+20.2KB(new) @base-ui-components/react/dialogparsed:${\tiny{\color{orangered}▲}}$+52.5KB(new) gzip:${\tiny{\color{orangered}▲}}$+17.6KB(new) @base-ui-components/react/alert-dialogparsed:${\tiny{\color{orangered}▲}}$+52.2KB(new) gzip:${\tiny{\color{orangered}▲}}$+17.5KB(new)

Show 31 more bundle changes

@base-ui-components/react/number-fieldparsed:${\tiny{\color{orangered}▲}}$+28.9KB(new) gzip:${\tiny{\color{orangered}▲}}$+10.3KB(new) @base-ui-components/react/tabsparsed:${\tiny{\color{orangered}▲}}$+26.6KB(new) gzip:${\tiny{\color{orangered}▲}}$+9.15KB(new) @base-ui-components/react/toastparsed:${\tiny{\color{orangered}▲}}$+26.4KB(new) gzip:${\tiny{\color{orangered}▲}}$+9.52KB(new) @base-ui-components/react/sliderparsed:${\tiny{\color{orangered}▲}}$+24.5KB(new) gzip:${\tiny{\color{orangered}▲}}$+9.22KB(new) @base-ui-components/react/accordionparsed:${\tiny{\color{orangered}▲}}$+23.1KB(new) gzip:${\tiny{\color{orangered}▲}}$+7.98KB(new) @base-ui-components/react/radio-groupparsed:${\tiny{\color{orangered}▲}}$+20.4KB(new) gzip:${\tiny{\color{orangered}▲}}$+7.76KB(new) @base-ui-components/react/menubarparsed:${\tiny{\color{orangered}▲}}$+19.7KB(new) gzip:${\tiny{\color{orangered}▲}}$+7.34KB(new) @base-ui-components/react/toolbarparsed:${\tiny{\color{orangered}▲}}$+19.6KB(new) gzip:${\tiny{\color{orangered}▲}}$+6.85KB(new) Base UI checkboxparsed:${\tiny{\color{orangered}▲}}$+18.7KB(new) gzip:${\tiny{\color{orangered}▲}}$+7.01KB(new) @base-ui-components/react/checkboxparsed:${\tiny{\color{orangered}▲}}$+18.7KB(new) gzip:${\tiny{\color{orangered}▲}}$+7.01KB(new) @base-ui-components/react/collapsibleparsed:${\tiny{\color{orangered}▲}}$+18.1KB(new) gzip:${\tiny{\color{orangered}▲}}$+6.28KB(new) @base-ui-components/react/scroll-areaparsed:${\tiny{\color{orangered}▲}}$+15.8KB(new) gzip:${\tiny{\color{orangered}▲}}$+5.63KB(new) @base-ui-components/react/radioparsed:${\tiny{\color{orangered}▲}}$+15KB(new) gzip:${\tiny{\color{orangered}▲}}$+5.7KB(new) @base-ui-components/react/switchparsed:${\tiny{\color{orangered}▲}}$+14.6KB(new) gzip:${\tiny{\color{orangered}▲}}$+5.59KB(new) @base-ui-components/react/toggle-groupparsed:${\tiny{\color{orangered}▲}}$+13.8KB(new) gzip:${\tiny{\color{orangered}▲}}$+5.36KB(new) @base-ui-components/react/fieldparsed:${\tiny{\color{orangered}▲}}$+13.8KB(new) gzip:${\tiny{\color{orangered}▲}}$+5.28KB(new) @base-ui-components/react/checkbox-groupparsed:${\tiny{\color{orangered}▲}}$+12.1KB(new) gzip:${\tiny{\color{orangered}▲}}$+4.77KB(new) @base-ui-components/react/inputparsed:${\tiny{\color{orangered}▲}}$+10.9KB(new) gzip:${\tiny{\color{orangered}▲}}$+4.38KB(new) @base-ui-components/react/toggleparsed:${\tiny{\color{orangered}▲}}$+8.99KB(new) gzip:${\tiny{\color{orangered}▲}}$+3.66KB(new) @base-ui-components/react/utilsparsed:${\tiny{\color{orangered}▲}}$+8.17KB(new) gzip:${\tiny{\color{orangered}▲}}$+3.15KB(new) @base-ui-components/react/progressparsed:${\tiny{\color{orangered}▲}}$+7.48KB(new) gzip:${\tiny{\color{orangered}▲}}$+3.04KB(new) @base-ui-components/react/meterparsed:${\tiny{\color{orangered}▲}}$+7.36KB(new) gzip:${\tiny{\color{orangered}▲}}$+3.03KB(new) @base-ui-components/react/avatarparsed:${\tiny{\color{orangered}▲}}$+7.22KB(new) gzip:${\tiny{\color{orangered}▲}}$+2.89KB(new) @base-ui-components/react/fieldsetparsed:${\tiny{\color{orangered}▲}}$+5.93KB(new) gzip:${\tiny{\color{orangered}▲}}$+2.47KB(new) @base-ui-components/react/formparsed:${\tiny{\color{orangered}▲}}$+5.74KB(new) gzip:${\tiny{\color{orangered}▲}}$+2.46KB(new) @base-ui-components/react/separatorparsed:${\tiny{\color{orangered}▲}}$+4.28KB(new) gzip:${\tiny{\color{orangered}▲}}$+1.84KB(new) @base-ui-components/react/use-renderparsed:${\tiny{\color{orangered}▲}}$+3.84KB(new) gzip:${\tiny{\color{orangered}▲}}$+1.67KB(new) @base-ui-components/react/unstable-use-media-queryparsed:${\tiny{\color{orangered}▲}}$+1.95KB(new) gzip:${\tiny{\color{orangered}▲}}$+941B(new) @base-ui-components/react/merge-propsparsed:${\tiny{\color{orangered}▲}}$+1.55KB(new) gzip:${\tiny{\color{orangered}▲}}$+764B(new) @base-ui-components/react/unstable-no-ssrparsed:${\tiny{\color{orangered}▲}}$+1.27KB(new) gzip:${\tiny{\color{orangered}▲}}$+681B(new) @base-ui-components/react/direction-providerparsed:${\tiny{\color{orangered}▲}}$+644B(new) gzip:${\tiny{\color{orangered}▲}}$+390B(new)

Details of bundle changes

Generated by :no_entry_sign: dangerJS against f1f2b1f64fb5934287b055689c353336dedcbe73

mui-bot avatar Apr 28 '25 14:04 mui-bot

Open in StackBlitz

npm i https://pkg.pr.new/@base-ui-components/react@1791

commit: f1f2b1f

pkg-pr-new[bot] avatar May 06 '25 12:05 pkg-pr-new[bot]

These changes look good. However, I noticed that the icons in the bundle size report look unreadable in light mode:

image

michaldudak avatar May 19 '25 11:05 michaldudak

I noticed that the icons in the bundle size report look unreadable in light mode:

Will change it to something that works better for both themes:

Screenshot 2025-05-19 at 16 20 48

Screenshot 2025-05-19 at 16 21 27

Janpot avatar May 19 '25 14:05 Janpot

For #201

oliviertassinari avatar May 19 '25 16:05 oliviertassinari

Oh, and mind you that I updated it to allow for arbitrary code if you want to check something custom:

// bundle-size/bundle-size-checker.config.mjs

      {
        id: 'custom-entry',
        code: `
          import { Field } from '@base-ui-components/react/field';
          console.log(Field.Root, Field.Label);
        `,
        externals,
      },

(Doesn't accept jsx yet I just noticed, but will look into that)

Janpot avatar May 20 '25 12:05 Janpot

I checked https://bundlephobia.com/package/@base-ui-components/[email protected] and it shows drastically different values. Do you have any idea where this difference might come from? One reason could be measuring a different version (alpha.8 vs. the latest master), but it's hard to believe we almost doubled the library size since the latest release.

michaldudak avatar May 28 '25 15:05 michaldudak

bundlejs also measures around 100KB gzipped

Bundle size is 316 kB -> 100 kB (gzip)

In general we should be wary of bundlephobia stats. They for instance also measure the data grid at 47B.

Janpot avatar May 28 '25 18:05 Janpot

Also working on an experimental vite version of the bundle size monitor, it shows similar results to the webpack one within a tolerance of ~1KB.

bundlephobia is built with package-build-stats. Looks like they also do a webpack build and analyze the stats.json, with externals from peer dependencies. Haven't looked any deeper yet how they calculate their sizes.

Janpot avatar May 29 '25 09:05 Janpot