Dogstudio / highway

Highway - A Modern Javascript Transitions Manager
https://highway.js.org/
MIT License
1.43k stars 92 forks source link

Highway bundle size #73

Closed mikehwagz closed 4 years ago

mikehwagz commented 4 years ago

Hi Dogstudio team! Big fan of Highway πŸ™‚

Noticed recently that the bundle size of Highway has mysteriously grown to a whopping 19kb gzipped while the website still advertises Highway as being 2.5kb gzipped. So, I decided to dig in and try to get to the bottom of this.

Seems like the culprit is these lines in the webpack config file which add massive overhead in core-js polyfills. Personally, I don't think it makes sense to ship polyfills in a library, period. Transpiling newer syntax to avoid errors in older browsers is crucial, but decisions around how and when to use and load polyfills should be left to the end-user of the library. Not only does this allow us to ship the smallest possible iteration of Highway to users that may or may not even need to support older browsers, but also because it is common practice to exclude node_modules from babel, so that means it would actually be very likely to accidentally include all that core-js overhead twice.

After removing those @babel/preset-env options mentioned above and implementing the async-to-promises babel transform, the gzipped build is down to 3.5kb πŸŽ‰and it's working smoothly in a few of my existing Highway projects.

After sifting through the Highway source code, I believe the only polyfills that would be potentially necessary for users to maintain existing browser support would be:

These polyfills can either be installed manually, or loaded dynamically in browsers that need them via polyfill.io. Simply include this script tag before highway:

<script src="https://polyfill.io/v3/polyfill.min.js?features=fetch%2CPromise%2CMap"></script>

This would be a breaking change for any Highway users that are not already including polyfills for those features in older browsers, but IMHO shaving off nearly 16.5kb from the gzipped bundle is well worth it.

Looking forward to your feedback. Happy to make a PR.

mikehwagz commented 4 years ago

Update: Experimented with replacing webpack with microbundle and the results are excellent. Using a single command npx microbundle src/highway.js --external none microbundle generates cjs, umd, and module outputs. Sizes below. As you can see, gzipped builds are down to ~2.5kb and brotli compression gets us down to ~2.2kb πŸ‘

2.46 kB: highway.js.gz
2.19 kB: highway.js.br
2.46 kB: highway.mjs.gz
2.19 kB: highway.mjs.br
2.52 kB: highway.umd.js.gz
2.23 kB: highway.umd.js.br
Anthodpnt commented 4 years ago

Great! Thanks @mikehwagz for the heads up! We'll take a look at it closely as soon as possible. Do you have time to prepare a clean pull request for those optimisations ?

mikehwagz commented 4 years ago

Hi @Anthodpnt, happy to put together a PR. Hopefully will get to it either today or later this week πŸ‘