[code-infra] Add bundle size monitor
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:
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...Use your smartphone camera to open QR code link. |
To edit notification comments on pull requests, go to your Netlify project configuration.
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/react parsed:${\tiny{\color{orangered}▲}}$+308KB(new) gzip:${\tiny{\color{orangered}▲}}$+92.6KB(new) @base-ui-components/react/menu parsed:${\tiny{\color{orangered}▲}}$+114KB(new) gzip:${\tiny{\color{orangered}▲}}$+37.8KB(new) @base-ui-components/react/context-menu parsed:${\tiny{\color{orangered}▲}}$+113KB(new) gzip:${\tiny{\color{orangered}▲}}$+36.9KB(new) @base-ui-components/react/select parsed:${\tiny{\color{orangered}▲}}$+111KB(new) gzip:${\tiny{\color{orangered}▲}}$+37.1KB(new) @base-ui-components/react/popover parsed:${\tiny{\color{orangered}▲}}$+86.1KB(new) gzip:${\tiny{\color{orangered}▲}}$+29KB(new) @base-ui-components/react/navigation-menu parsed:${\tiny{\color{orangered}▲}}$+84.9KB(new) gzip:${\tiny{\color{orangered}▲}}$+28.5KB(new) @base-ui-components/react/tooltip parsed:${\tiny{\color{orangered}▲}}$+63.9KB(new) gzip:${\tiny{\color{orangered}▲}}$+21.6KB(new) @base-ui-components/react/preview-card parsed:${\tiny{\color{orangered}▲}}$+59.2KB(new) gzip:${\tiny{\color{orangered}▲}}$+20.2KB(new) @base-ui-components/react/dialog parsed:${\tiny{\color{orangered}▲}}$+52.5KB(new) gzip:${\tiny{\color{orangered}▲}}$+17.6KB(new) @base-ui-components/react/alert-dialog parsed:${\tiny{\color{orangered}▲}}$+52.2KB(new) gzip:${\tiny{\color{orangered}▲}}$+17.5KB(new)
Show 31 more bundle changes
@base-ui-components/react/number-field parsed:${\tiny{\color{orangered}▲}}$+28.9KB(new) gzip:${\tiny{\color{orangered}▲}}$+10.3KB(new) @base-ui-components/react/tabs parsed:${\tiny{\color{orangered}▲}}$+26.6KB(new) gzip:${\tiny{\color{orangered}▲}}$+9.15KB(new) @base-ui-components/react/toast parsed:${\tiny{\color{orangered}▲}}$+26.4KB(new) gzip:${\tiny{\color{orangered}▲}}$+9.52KB(new) @base-ui-components/react/slider parsed:${\tiny{\color{orangered}▲}}$+24.5KB(new) gzip:${\tiny{\color{orangered}▲}}$+9.22KB(new) @base-ui-components/react/accordion parsed:${\tiny{\color{orangered}▲}}$+23.1KB(new) gzip:${\tiny{\color{orangered}▲}}$+7.98KB(new) @base-ui-components/react/radio-group parsed:${\tiny{\color{orangered}▲}}$+20.4KB(new) gzip:${\tiny{\color{orangered}▲}}$+7.76KB(new) @base-ui-components/react/menubar parsed:${\tiny{\color{orangered}▲}}$+19.7KB(new) gzip:${\tiny{\color{orangered}▲}}$+7.34KB(new) @base-ui-components/react/toolbar parsed:${\tiny{\color{orangered}▲}}$+19.6KB(new) gzip:${\tiny{\color{orangered}▲}}$+6.85KB(new) Base UI checkbox parsed:${\tiny{\color{orangered}▲}}$+18.7KB(new) gzip:${\tiny{\color{orangered}▲}}$+7.01KB(new) @base-ui-components/react/checkbox parsed:${\tiny{\color{orangered}▲}}$+18.7KB(new) gzip:${\tiny{\color{orangered}▲}}$+7.01KB(new) @base-ui-components/react/collapsible parsed:${\tiny{\color{orangered}▲}}$+18.1KB(new) gzip:${\tiny{\color{orangered}▲}}$+6.28KB(new) @base-ui-components/react/scroll-area parsed:${\tiny{\color{orangered}▲}}$+15.8KB(new) gzip:${\tiny{\color{orangered}▲}}$+5.63KB(new) @base-ui-components/react/radio parsed:${\tiny{\color{orangered}▲}}$+15KB(new) gzip:${\tiny{\color{orangered}▲}}$+5.7KB(new) @base-ui-components/react/switch parsed:${\tiny{\color{orangered}▲}}$+14.6KB(new) gzip:${\tiny{\color{orangered}▲}}$+5.59KB(new) @base-ui-components/react/toggle-group parsed:${\tiny{\color{orangered}▲}}$+13.8KB(new) gzip:${\tiny{\color{orangered}▲}}$+5.36KB(new) @base-ui-components/react/field parsed:${\tiny{\color{orangered}▲}}$+13.8KB(new) gzip:${\tiny{\color{orangered}▲}}$+5.28KB(new) @base-ui-components/react/checkbox-group parsed:${\tiny{\color{orangered}▲}}$+12.1KB(new) gzip:${\tiny{\color{orangered}▲}}$+4.77KB(new) @base-ui-components/react/input parsed:${\tiny{\color{orangered}▲}}$+10.9KB(new) gzip:${\tiny{\color{orangered}▲}}$+4.38KB(new) @base-ui-components/react/toggle parsed:${\tiny{\color{orangered}▲}}$+8.99KB(new) gzip:${\tiny{\color{orangered}▲}}$+3.66KB(new) @base-ui-components/react/utils parsed:${\tiny{\color{orangered}▲}}$+8.17KB(new) gzip:${\tiny{\color{orangered}▲}}$+3.15KB(new) @base-ui-components/react/progress parsed:${\tiny{\color{orangered}▲}}$+7.48KB(new) gzip:${\tiny{\color{orangered}▲}}$+3.04KB(new) @base-ui-components/react/meter parsed:${\tiny{\color{orangered}▲}}$+7.36KB(new) gzip:${\tiny{\color{orangered}▲}}$+3.03KB(new) @base-ui-components/react/avatar parsed:${\tiny{\color{orangered}▲}}$+7.22KB(new) gzip:${\tiny{\color{orangered}▲}}$+2.89KB(new) @base-ui-components/react/fieldset parsed:${\tiny{\color{orangered}▲}}$+5.93KB(new) gzip:${\tiny{\color{orangered}▲}}$+2.47KB(new) @base-ui-components/react/form parsed:${\tiny{\color{orangered}▲}}$+5.74KB(new) gzip:${\tiny{\color{orangered}▲}}$+2.46KB(new) @base-ui-components/react/separator parsed:${\tiny{\color{orangered}▲}}$+4.28KB(new) gzip:${\tiny{\color{orangered}▲}}$+1.84KB(new) @base-ui-components/react/use-render parsed:${\tiny{\color{orangered}▲}}$+3.84KB(new) gzip:${\tiny{\color{orangered}▲}}$+1.67KB(new) @base-ui-components/react/unstable-use-media-query parsed:${\tiny{\color{orangered}▲}}$+1.95KB(new) gzip:${\tiny{\color{orangered}▲}}$+941B(new) @base-ui-components/react/merge-props parsed:${\tiny{\color{orangered}▲}}$+1.55KB(new) gzip:${\tiny{\color{orangered}▲}}$+764B(new) @base-ui-components/react/unstable-no-ssr parsed:${\tiny{\color{orangered}▲}}$+1.27KB(new) gzip:${\tiny{\color{orangered}▲}}$+681B(new) @base-ui-components/react/direction-provider parsed:${\tiny{\color{orangered}▲}}$+644B(new) gzip:${\tiny{\color{orangered}▲}}$+390B(new)
Generated by :no_entry_sign: dangerJS against f1f2b1f64fb5934287b055689c353336dedcbe73
These changes look good. However, I noticed that the icons in the bundle size report look unreadable in light mode:
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:
For #201
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)
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.
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.
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.