Fighting Bloated Software

Curran Kelleher
3 min readJun 18, 2018

--

All I wanted to do was create a Web app with authentication.

I started with the excellent project nextjs-starter. The excitement was building when I got authentication to work locally. I gutted the starter content, hoping to achieve a “clean slate”. It appears clean enough, but does it load clean?

How long would it take to load on slow 3G? 23 seconds. Not Good.

Out of the gate, the HTML coming down from the server is 247Kb, and the main JS bundle is a whopping 628Kb. Since when is “Hello World” 1Mb? WTF is this?

Innocuous “starter” dependencies.

The Gardener

I am an aspiring gardener. I want to plant seeds and tend to them as they grow. Buying pre-grown plants would be the quickest way to set up my garden. But what kind of gardener would I be?

Projects like nextjs-starter and Bootstrap are well intended enough. They help developers start with something quickly. But at what cost?

In a first attempt at “gutting” the starter project, I left in all the “starter dependencies”, like Bootstrap, JQuery, and about 25 others, so the authentication flow and appearance would not break. Having observed the bloated build, I feel I must gut everything except the bare minimum authentication flow. The pains of rolling your own authentication flow is why I want to use this particular starter project in the first place.

Gutting CSS

It turns out that the HTML coming down from the server is 247Kb of CSS.

Why do I need Ionicons again?

By some unfortunate twist of fate, the “production build” of the starter project is spitting out unminified CSS of a handful of libraries concatenated together.

The culprit is of course `css/index.scss`, which is pulling these in.

Essential starter CSS.

Yeah so I’ll just delete everything here and remove those dependencies from package.json, thank you very much. Oh and I think I’ll delete css/nojs-menus.scsswhile I’m at it, which appears to be a whole library dropped into the project rather than added as a dependency.

Fortunately, all the essential elements of the authentication flows still work!

The essentials are still working without all that CSS.

Removing that CSS reduced the initial HTML payload from 247Kb to 2.9Kb. This feels so right.

Gutting JS

What’s in our 628Kb JS bundle anyway? I bet it’s the JS counterparts of the CSS libraries we removed. I’m going to delete all dependencies I don’t think are useful. These include jquery, popper.js(Bootstrap’s faithful friends), reactstrap, react-syntax-highlighter, and react-transition-group.

The next exercise is refactoring all the starter code that uses reactstrap . This consisted of replacing things like <Container> with <div>. In fact, I did a blanket text replace for all Reactstrap imports, replacing them all with <div>(except Form became form, and Input became input).

For fellow Vim nerds:
:%s/Row\|Col\|Label\|Button\|FormGroup/div/g
:%s/Form/form/g
:%s/Input/input/g

This can be deleted.

Removing those dependencies reduced JS bundle size from 628Kb to 254Kb.

Now only 10 seconds on slow 3G.

I still feel like it should be smaller, but this is the price of shiny things.

Time to plant my seeds.

[Update]

The gutted code is here:
* https://github.com/iaincollins/nextjs-starter/pull/86
* https://github.com/curran/nextjs-starter/tree/aggressive-gutting

Also I learned later about the smaller starter example https://github.com/iaincollins/next-auth/tree/master/example

--

--

Curran Kelleher
Curran Kelleher

Responses (2)