How we shrunk our react bundle size to less than 50%?
tldr; be careful which npm modules you want to include in your production bundle.
vaamo has been using React for approximately one year now. First, we built a small feature integrated within our existing frontend stack. This was a good situation to learn React and prepare for a following project that completely relied on React and NodeJS and retrieved only its data from our backend API. Having gained some experience, we built a third frontend using React and Redux later last year.
Having built our new website www.vaamo.de continuously measuring the performance with Calibre App I got very sensitive to pageload times, the amount of transferred data and other performance measures. Therefore I was shocked by a bundle size of more than 2 MB and felt the need to do something about it.
I did some research and came up with different strategies to improve performance:
- switch to webpack that supposedly uses better compression,
- implement code splitting and only use the code you need,
- use tree-shaking.
All of them would have been a lot of work and eventually I found the npm module Disc when I wanted to determine the amount of module dependencies within our bundle. As our application is rather small, around 90% of the bundle’s contents are npm dependencies. Thus code-splitting would not have helped that much anyway. But Disc revealed one important fact: due to using Stilr to write our styles and using autoprefixer to automatically prefix everything in the last step we were dependent on caniuse-db so autoprefixer is able to figure out which styles to prefix depending on the selected browser version coverage. The dependency on caniuse-db solely increased our bundle size by 1.2 MB.
Diving deeper into our usage of Stilr I realized that it wouldn’t be necessary to include autoprefixer and caniuse-db into our bundle because all our styles, which were written into a style tag of the bundle serving html file, should really belong into an external stylesheet that would be written once during a build step and then be included in the html markup. Pairing with my teammates we were able to perform these steps and then exclude autoprefixer and caniuse-db from our production bundle. This saved us about 50% in file size.