Since the minification happens in the PHP server at runtime, even with a read through cache tradeoffs were made so that the server could minify in a performant way, giving up size gains for speed.
There are gains to be had if we were to use node based minifiers and just give the smallest possible bundle to ResourceLoader for serving.
Given we have introduced a build step previously, the solution seemed pretty straightforward.
We discussed we would introduce a minification step as part of the build process, and then the committed assets in /resources/dist would be minified and as small as possible.
We first did research and got numbers to check if there would actually be any gains and if it would be worth it. You can read about it here:
- Architecture design record 8. Enable minification of bundle with UglifyJS
- mediawiki.org: Extension:Popups/Minifying assets with uglifyjs
Then researched how to best introduce the minifier. As a standalone CLI we could run it in our now single index.js file, but if we leveraged other bundler features like multiple entry points or code splitting then the minification commands could become very complex.
As such, we chose to integrate the minifier as a plugin to the webpack bundler. See uglifyjs-webpack-plugin.
We added UglifyJS minification via Webpack (config).
Minifying via UglifyJS brought the bundle size down from the previous version ~40%, gzipped ~25%.
Also, theoretically, with EcmaScript modules webpack with uglify can perform tree shaking of unused code. Webpack will mark unused exports which would then be removed in the production bundle by uglify. See the guide Tree shaking.
Initially we had to do some research to instruct ResourceLoader to not apply minification to this already minified files. What we wanted was to avoid it so that the source maps comment would be preserved, and then we would have source maps on the production version of the code.
In the end, we had to give up, and ended up removing the banner as it interfered with the minification of other modules in production, but we still have source maps in development.
This was a pretty straight forward addition that brought us benefits with little cost. It was enabled by the change to introduce a build step.
The gain in size is not super significant given how small the JS code base is, but if applied to bigger code bases we could get great improvements for free.
- Table of contents
- Next post: Fast and isolated JS unit tests