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.

You may have read “How it feels to learn JavaScript in 2016” and be or not be familiar with the confusingly vast amount of new Javascript frameworks and libraries. Often one does not have the time to upgrade everything to the newest best-practices or the most hyped library. This is the reason that in all the three projects we still use browserify to create our production bundle.

Having built our new website 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.