Skip to content

[gui] Speed up the web UI build - #5179

Open
barnabasdomozi wants to merge 1 commit into
Ericsson:masterfrom
barnabasdomozi:webpack_build
Open

barnabasdomozi wants to merge 1 commit into
Ericsson:masterfrom
barnabasdomozi:webpack_build

Conversation

@barnabasdomozi

@barnabasdomozi barnabasdomozi commented Nov 6, 2026 •

Copy link
Copy Markdown
Collaborator

A clean build of the web UI (npm run build, also run by make package)
took about 76 seconds. It now takes about 8 seconds.

Root causes

  1. The whole Vuetify stylesheet was compiled again for every component.
    src/variables.scss started with @use 'vuetify/styles'. Webpack adds
    this file to the top of every SCSS/Sass <style> block, so the full
    Vuetify CSS (about 350 KB) was compiled and bundled once per component,
    about 56 times. This was most of the build time. It also made the output
    twice as big (32 MB instead of 15 MB) and main.js 7 MB instead of 1 MB.
    main.js already imports vuetify/styles once, so these copies were not
    needed.

  2. The JavaScript minifier was slow. Webpack uses Terser by default, which
    runs in JavaScript and makes two passes over the code.

  3. Babel did more work than needed. Without a browser target it converted
    all code down to old ES5 syntax, and it also processed the whole Vuetify
    library from node_modules.

Fixes

  • variables.scss now only contains Sass variables, so it no longer outputs
    any CSS. The :root color variables moved to a new src/global.css file,
    imported once from main.js. A comment in variables.scss explains why
    CSS must not be put there.
  • Minify with esbuild (through minimizer-webpack-plugin, which webpack
    already uses) instead of Terser.
  • Add a fixed "browserslist" target to package.json (Chrome and Edge 80+,
    Firefox 78+, Safari 14+), and stop running Babel on packages in
    node_modules. This is the same minimum that Vue, Vuetify and the other
    libraries already need, because they use ES2020 syntax. It also matches
    the esbuild target (es2020).
  • Let webpack clean the dist folder (output.clean) instead of running
    rimraf before the build.
  • Clear the webpack cache when any build config file, package.json or
    .babelrc changes, not only when webpack.common.js changes.
  • Makefile: do not run npm install twice when the UI has to be rebuilt.
  • Remove vue.config.js, a leftover from Vue CLI that nothing reads.
  • Fix v-model on a constant in RunList.vue and
    ListReviewStatusRules.vue (itemsPerPageOptions). esbuild warned that
    this assignment would throw. It is now a one-way :items-per-page-options
    binding.

Results

Clean build with an empty cache, measured on the same machine.

Before After
npm run build (total) 76 s 8 s
webpack compile time 72 s 6.1 s
dist size 32 MB 15 MB

This PR was mainly generated by AI.

A clean build of the web UI (`npm run build`, also run by `make package`)
took about 76 seconds. It now takes about 8 seconds.

Root causes
-----------

1. The whole Vuetify stylesheet was compiled again for every component.
   `src/variables.scss` started with `@use 'vuetify/styles'`. Webpack adds
   this file to the top of every SCSS/Sass `<style>` block, so the full
   Vuetify CSS (about 350 KB) was compiled and bundled once per component,
   about 56 times. This was most of the build time. It also made the output
   twice as big (32 MB instead of 15 MB) and `main.js` 7 MB instead of 1 MB.
   `main.js` already imports `vuetify/styles` once, so these copies were not
   needed.

2. The JavaScript minifier was slow. Webpack uses Terser by default, which
   runs in JavaScript and makes two passes over the code.

3. Babel did more work than needed. Without a browser target it converted
   all code down to old ES5 syntax, and it also processed the whole Vuetify
   library from node_modules.

Fixes
-----

- `variables.scss` now only contains Sass variables, so it no longer outputs
  any CSS. The `:root` color variables moved to a new `src/global.css` file,
  imported once from `main.js`. A comment in `variables.scss` explains why
  CSS must not be put there.
- Minify with esbuild (through `minimizer-webpack-plugin`, which webpack
  already uses) instead of Terser.
- Add a fixed "browserslist" target to package.json (Chrome and Edge 80+,
  Firefox 78+, Safari 14+), and stop running Babel on packages in
  node_modules. This is the same minimum that Vue, Vuetify and the other
  libraries already need, because they use ES2020 syntax. It also matches
  the esbuild target (es2020).
- Let webpack clean the `dist` folder (`output.clean`) instead of running
  `rimraf` before the build.
- Clear the webpack cache when any build config file, package.json or
  .babelrc changes, not only when `webpack.common.js` changes.
- Makefile: do not run `npm install` twice when the UI has to be rebuilt.
- Remove `vue.config.js`, a leftover from Vue CLI that nothing reads.
- Fix `v-model` on a constant in `RunList.vue` and
  `ListReviewStatusRules.vue` (`itemsPerPageOptions`). esbuild warned that
  this assignment would throw. It is now a one-way `:items-per-page-options`
  binding.

Results
-------

Clean build with an empty cache, measured on the same machine.

|                         | Before | After  |
| ----------------------- | ------ | ------ |
| `npm run build` (total) | 76 s   | 8 s    |
| webpack compile time    | 72 s   | 6.1 s  |
| `dist` size             | 32 MB  | 15 MB  |

This PR was mainly generated by AI.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants