Increase conversion with a faster web app

50% of users will leave if your site doesn’t load in less than 3 seconds.

Gav McKenzie
Author
Gav McKenzie
Published
May 8, 2018
Topics
How-to, Industry

We’re always trying to squeeze out extra speed from our Web Apps at Etch.

There are the common things you can do, like…

…but let’s dive into some of the lesser known ways of speeding up your app.

Import statements

Depending on how you import your JavaScript modules, you could be needlessly bloating your app.

The problem

We found that, with both lodash and React Bootstrap, importing a named export from a module using the object style notation actually imported the entire library!

// Bad times, imports whole library
import { foo } from 'bar';

This is because importing from the root of the module bar loaded the index.js file and just extracted one exported variable from it, but it still has to load the whole file.

// index.js
export foo from './foo';
export bar from './bar';
export baz from './baz';
// etc

The solution

Whilst this style of import looks nice and is super convenient, it can be more efficient on your bundle size to import each individual module.

// Good times, imports only the code we need
import foo from 'bar/foo';

Bundle analysis

So how do you find those modules that are needlessly bloating your app? You need a bundle analyser! We were trying to figure out why our bundles were so large, and turned to the internet to help.

There’s a couple of great solutions, depending on which bundling route you favour: webpack or browserify.

Webpack bundle analyser

Output from webpack visualizerOutput from webpack visualizer

There’s a couple of routes here, even within webpack. webpack visualizer and webpack bundle analyzer will both output an awesome visual representation of your bundle, showing how much space is taken up be each module.

Digging in to these can help inform you where you need to trim the fat in your webpack bundle.

Disc for browserify

If you’re not using webpack, you’re probably using browserify. Disc for browserify looks pretty similar to the webpack visualizer, but runs an analysis on your browserify bundle to tell you what’s taking up too much space.

Output from discOutput from disc

React production mode and uglify

Whilst checking out our bundles, we noticed that react-dom.development.js was being loaded and taking up a ton of space. The word “development” was a bit of a warning sign so we investigated why it was being loaded.

React-dom is littered with if statements checking what to do based on an environment variable of NODE_ENV. If this is not set to 'production' you get lots of extra information in your console errors and a bunch of other things that make development easier.

In production you don’t really want any of that so you need to set NODE_ENV to production. This prevents a bunch of unnecessary imports thus cutting your bundle size down.

Bonus with uglify-js

You can combine this with uglify-js (note: with the hyphen, not the other one) which will strip out unnecessary code (such as if statements) whilst minifying your JavaScript. All the if (NODE_ENV === 'production') checks are stripped out.

This both makes your bundle size smaller and reduces the runtime by removing unnecessary calculations in the browser.

The React site has an excellent writeup on setting this up in common build processes.

Code linting

Linting your code is always a great idea, but linting your CSS and JavaScript can have the unexpected effect of reducing your app size.

If you care about speed, you’re probably compressing your assets with GZIP. GZIP uses a couple of clever algorithms to make your code smaller: LZ77 and Huffman coding.

The interesting one for us is LZ77.

The LZ77 algorithm replaces repeated occurrences of data with references.

*“Repeated occurances” *being the important bit. If we can make our code as similar as possible with repeating patterns, GZIP can compress it more efficiently.

A linter will enforce a strict coding style on your team. Things like keeping CSS properties in alphabetical order, enforcing number of spaces, when new lines happen, etc, can let GZIP do its job better and keep your bundle size down.

You can build this into your text editor, your pre-commit hooks, and your continuous integration process for maximum power.

Service Workers

People are pretty excited about using service workers for offline support, but what about online support?

At the point a user lands on your app, you can use service workers to fetch the commonly required assets they might need in their onward journey in the background. This will reduce page load times as they move through the app/site.

If you have a lot of returning users, you can use service workers to make sure their experience only gets better. Cache your CSS and JS bundles so that load time is virtually instant upon returning to your app/site.

TL;DR

At Etch, we like our Web Apps to be fast. A good starting point is to; clean up your imports, analyse your bundles, lint your code and switch to production mode, or… watch your users leave.

Hopefully you’ve found a couple of ideas to help you speed up your Web App and maybe even increase your conversion rate.