This feature will be completed in two phases to provide maximum impact as soon as possible.
✅ Phase 1
Includes CI/local builds & reporting on PRs. We want to test different scenarios (current tooling tests a single export). For example, we can measure impact of build time and runtime version of makeStyles(). It will be possible with fixtures.
Fixtures
Are defined in Storybook like format:
- file body contains imports and code to measure
- default export initially used to provide a name for a fixture, but later we can expand this if needed
A fixture for runtime version for @fluentui/react-make-styles
import { makeStyles, mergeClasses } from "@fluentui/react-make-styles";
// ^ necessary imports
console.log(makeStyles, mergeClasses);
// ^ console.log() is a simplest way to ensure that required imports will be kept in a bundle
export default {
name: "makeStyles + mergeClasses (runtime)"
};
// ^ will be removed during build to be skipped from results
A fixture for build time version for @fluentui/react-make-styles
import { __styles, mergeClasses } from "@fluentui/react-make-styles";
console.log(__styles, mergeClasses);
export default {
name: "makeStyles + mergeClasses (build time)"
};
Research
Before implementing a custom solution we should ensure that there is nothing that we can reuse.
research results
Size Auditor (existing tool)
- No support for scoped builds (requires to build everything)
- No measurements for GZIP sizes (shows only minified sizes)
- No public analysis i.e. dashboard
- hard to grab a report as on PRs as it shows only changed entries
- Github action builds base and current branches (double build)
- Outputs only minified size
- Will require custom builds in our scenario
Material UI
Has own tooling and reporting via danger.js.
- Nice reporting, but still not suitable for monorepo
- Provides only CLI output and minified sizes (build is required by us)
https://github.com/pkg-size/pkg-size/blob/f907c58f32b50abb61a7be1188e0290d27c1d071/src/pkg-size.ts#L36-L40
- Github action builds base and current branches (double build)
https://github.com/pkg-size/action/blob/cc5eef94b3703031cfc048ee8acbcf9bfbd35510/src/lib/generate-size-report.js#L41-L56
- Webpack 5 is not supported
- Works well for local rebuilds while we need to compare with another branch/master
https://github.com/GoogleChromeLabs/size-plugin/blob/cc61db7282c1f0642acc28ca8de0db57d3367971/src/index.js#L121-L129
✅ Local reporting (#18010)
Implements only local builds and reporting based of fixtures that are created per package. Is a base for other changes.
- Should work per package (to allow scoping)
- Use fixtures to measure different scenarios
- Relies on build artifacts (i.e. requires build first) as we want to test the same output as customers will consume
Sample output from CLI
yarn workspace @fluentui/react-make-styles bundle-size
yarn workspace v1.22.0
yarn run v1.22.0
$ bundle-size measure
[i] artifacts dir is cleared
[i] Measuring bundle size for 3 fixture(s)...
- bundle-size/makeStaticStyles-runtime.fixture.js
- bundle-size/makeStyles-runtime.fixture.js
- bundle-size/makeStyles.fixture.js
[i] "makeStaticStyles-runtime.fixture.js": Webpack in 0.92s
[i] "makeStaticStyles-runtime.fixture.js": Terser in 0.36s
[i] "makeStyles-runtime.fixture.js": Webpack in 0.27s
[i] "makeStyles-runtime.fixture.js": Terser in 0.54s
[i] "makeStyles.fixture.js": Webpack in 0.19s
[i] "makeStyles.fixture.js": Terser in 0.11s
┌────────────────────────────────────────┬───────────────┬───────────┐
│ Fixture │ Minified size │ GZIP size │
├────────────────────────────────────────┼───────────────┼───────────┤
│ makeStaticStyles (runtime) │ 8.51 kB │ 3.66 kB │
├────────────────────────────────────────┼───────────────┼───────────┤
│ makeStyles + mergeClasses (runtime) │ 22 kB │ 8.34 kB │
├────────────────────────────────────────┼───────────────┼───────────┤
│ makeStyles + mergeClasses (build time) │ 2.82 kB │ 1.34 kB │
└────────────────────────────────────────┴───────────────┴───────────┘
Completed in 2.75s
✅ Store results (#18322)
To avoid double builds we need to store our data (results for previous runs) somewhere, after discussion with @ling1726 we agreed to Azure Tables as the simplest and $$$ effective option. A storage account, tables and a resource group are completely separate from existing tools.
Current PR (#18322) uses Azure Tables directly on our side, this functionality will be re-implemented as a backend app and will be moved to Azure Functions.
We will currently store only the last build for a base branch (master, v7), this will allow us to implement comparisons locally and on CI.
✅ Local & CI comparison (#18256)
On this step we will focus on bundle-size comparison for CI and locally. The last step is important because no existing tools allow you to understand bundle size impact before pushing to CI.
Functionality will be implemented via an additional command that generates report for CLI & in Markdown:
A sample markdown report (results are random)
| Package & Exports |
Baseline (minified/GZIP) |
PR |
Change |
react-divider Divider |
17.892 kB
5.83 kB |
18.266 kB
5.941 kB |
374 B 
111 B  |
react-image Image |
11.521 kB
4.344 kB |
10.784 kB
4.238 kB |
-737 B 
-106 B  |
react-make-styles makeStaticStyles (runtime) |
8.27 kB
3.566 kB |
8.514 kB
3.66 kB |
244 B 
94 B  |
react-make-styles makeStyles + mergeClasses (runtime) |
21.926 kB
8.326 kB |
22.994 kB
8.841 kB |
1.068 kB 
515 B  |
react-make-styles makeStyles + mergeClasses (build time) |
2.67 kB
1.263 kB |
2.823 kB
1.342 kB |
153 B 
79 B  |
Any failures on increases will not be implemented on this step, only reporting. For reporting we will reuse existing functionality in our pipeline (GithubPRComment@0 task).
🛠 Phase 2
On this phase we will replace existing SizeAuditior with a new bundle size tool.
💭 Phase 3 (to be discussed)
- Publicly graph the size of each component over time
- Publicly graph the total size of the library over time
This feature will be completed in two phases to provide maximum impact as soon as possible.
✅ Phase 1
Includes CI/local builds & reporting on PRs. We want to test different scenarios (current tooling tests a single export). For example, we can measure impact of build time and runtime version of
makeStyles(). It will be possible with fixtures.Fixtures
Are defined in Storybook like format:
A fixture for runtime version for
@fluentui/react-make-stylesA fixture for build time version for
@fluentui/react-make-stylesResearch
Before implementing a custom solution we should ensure that there is nothing that we can reuse.
research results
Size Auditor (existing tool)
size-limit & Github action
Material UI
Has own tooling and reporting via danger.js.
pkg-size
https://github.com/pkg-size/pkg-size/blob/f907c58f32b50abb61a7be1188e0290d27c1d071/src/pkg-size.ts#L36-L40
https://github.com/pkg-size/action/blob/cc5eef94b3703031cfc048ee8acbcf9bfbd35510/src/lib/generate-size-report.js#L41-L56
size-plugin
https://github.com/GoogleChromeLabs/size-plugin/blob/cc61db7282c1f0642acc28ca8de0db57d3367971/src/index.js#L121-L129
preactjs/compressed-size-action
https://github.com/preactjs/preact/runs/2608423363?check_suite_focus=true
✅ Local reporting (#18010)
Implements only local builds and reporting based of fixtures that are created per package. Is a base for other changes.
Sample output from CLI
✅ Store results (#18322)
To avoid double builds we need to store our data (results for previous runs) somewhere, after discussion with @ling1726 we agreed to Azure Tables as the simplest and $$$ effective option. A storage account, tables and a resource group are completely separate from existing tools.
Current PR (#18322) uses Azure Tables directly on our side, this functionality will be re-implemented as a backend app and will be moved to Azure Functions.
We will currently store only the last build for a base branch (
master,v7), this will allow us to implement comparisons locally and on CI.✅ Local & CI comparison (#18256)
On this step we will focus on bundle-size comparison for CI and locally. The last step is important because no existing tools allow you to understand bundle size impact before pushing to CI.
Functionality will be implemented via an additional command that generates report for CLI & in Markdown:
A sample markdown report (results are random)
Divider
17.892 kB5.83 kB18.266 kB5.941 kB374 B111 BImage
11.521 kB4.344 kB10.784 kB4.238 kB-737 B-106 BmakeStaticStyles (runtime)
8.27 kB3.566 kB8.514 kB3.66 kB244 B94 BmakeStyles + mergeClasses (runtime)
21.926 kB8.326 kB22.994 kB8.841 kB1.068 kB515 BmakeStyles + mergeClasses (build time)
2.67 kB1.263 kB2.823 kB1.342 kB153 B79 BAny failures on increases will not be implemented on this step, only reporting. For reporting we will reuse existing functionality in our pipeline (
GithubPRComment@0task).🛠 Phase 2
On this phase we will replace existing SizeAuditior with a new bundle size tool.
@fluentui/react-components@fluentui/react-northstar@fluentui/react💭 Phase 3 (to be discussed)