← Thomas Lackemann

Reduce Your bundle.js File Size By Doing This One Thing

Posted on Jan 15, 2016 in

I’ve been building Single Page Applications for a couple years now and I’m always surprised at how many developers fail to think about the size of bundle.js.

“When we minify/uglify it will be fine.” ~ Someone, now dead to me

Even when we minify bundle.js we could be left with a gigantic application that takes a bit of time to load for slow or mobile connections. So how can we significantly cut back on this bloat?

Simple! Use relative file paths. Let’s look at two examples to show the difference.

Example 1

First, we’re going to write a simple example application using ES6 destructuring assignment to load some lodash modules.

# src/example.js

import { concat, sortBy, map, sample } from 'lodash';

// Example: sortBy
const users = [
  { 'user': 'fred',   'age': 48 },
  { 'user': 'barney', 'age': 36 },
  { 'user': 'fred',   'age': 42 },
  { 'user': 'barney', 'age': 34 }
];
const exampleSortBy = sortBy(users, function(o) { return o.user; });
console.log(exampleSortBy);

// Example: map
const exampleMap = map(users, 'user');
console.log(exampleMap);

// Example: concat
const array = [1];
const exampleConcat = concat(array, 2, [3], [[4]]);
console.log(exampleConcat);

// Example: sample
const exampleSample = sample([1, 2, 3, 4]);
console.log(exampleSample);

Let’s compile and bundle the above application using browserify:

browserify src/example.js -o dist/bundle.js -t [ babelify --presets [ es2015 ] ] -v -d -g uglifyify

So far so good, let’s write our next example and compare file sizes after.

Example 2

We’re going to write the exact same application but instead of loading all of lodash, we’ll use file paths to load our modules.

# src/example-2.js

import concat from 'lodash/concat';
import sortBy from 'lodash/sortBy';
import map from 'lodash/map';
import sample from 'lodash/sample';

// Example: sortBy
const users = [
  { 'user': 'fred',   'age': 48 },
  { 'user': 'barney', 'age': 36 },
  { 'user': 'fred',   'age': 42 },
  { 'user': 'barney', 'age': 34 }
];
const exampleSortBy = sortBy(users, function(o) { return o.user; });
console.log(exampleSortBy);

// Example: map
const exampleMap = map(users, 'user');
console.log(exampleMap);

// Example: concat
const array = [1];
const exampleConcat = concat(array, 2, [3], [[4]]);
console.log(exampleConcat);

// Example: sample
const exampleSample = sample([1, 2, 3, 4]);
console.log(exampleSample);

Now let’s compile:

browserify src/example-2.js -o dist/bundle-2.js -t [ babelify --presets [ es2015 ] ] -v -d -g uglifyify

Question: Which example do you think is smaller in file size?

Compare

Our applications do the exact same thing. It’s practically the exact same code, but if we compare our two files you’ll notice that Example 2 is significantly smaller!

$ ls -lha dist/
bundle-2.js (84K)
bundle.js (204K)

The reason is mentioned above: we’re not including all of lodash but instead including the files we specifically need.

This works for almost all node modules too. Simply replace your destructing assignment import statements with local path import statements and see the instant size reduction.

Source

If you want to see an example of this in action, you can check out the GitHub repository below.

https://github.com/tlackemann/minimize-bundle-js-size

Cheers, Tom


Edit 01/19/2016: I’ve received a lot of comments regarding Webpack2, Rollup, etc … Yes, these technologies are awesome and do a much needed service called “tree shaking” (which is excluding modules we don’t need, seen above) but if you’re inheriting a project or working on something existing, more likely than not you’re not using the “new shiny” technologies and need something more battle proven. The methodology used in this article is great for gaining quick-wins with existing codebases. Happy hacking :)

About

Tom is the CEO (Customer Experience Overlord) of Unicorn Heart Club where he leads development for Power Virtual TableTop. He's a homebrewer, hiker, and has an about page.

Read More

← What I Accomplished in 2015

Comments