Making your javascript resources load 30% faster

In my last article I wrote about my idea on how bundling javascript resources can save space and decrease the loading time. I have been working with this idea for quite some time and today I decided to put it down for some serious testing.

Skipping the long technical part, jbb is a serialisation format for javascript structures. It was originally designed to be a replacement to the dozens of different 3D model formats out there, trying to outperform - or par with - them in loading time. The operation principle is simple: You load your resources with node.js in the same way you do in the browser and you pack the them in a bundle. This will also bundle referred DOM elements, such as images, videos, sounds or scripts, making this format ideal for any kind of run-time resources.

For my tests, I decided to focus on the 3D models since they are the most demanding. I selected a variety of meshes in different formats, I encoded them to jbb and I compared the bundle size and loading speed. I was pleased to find out that in most of the cases, .jbb can speed-up the loading time up to 30%!

Picking source files

I browsed through the models in the three.js examples and I hand-picked a few candidates for the jbb encoder. I looked for the most wide-used file formats and for already optimised file formats in order to make the competition harder.

I then grouped them together and created five different source bundles, that can be tested individually. Each source bundle consists of an index file and the source model files in their original format.

The following table illustrates the bundles and their contents. Click on the number of files for more details:

Bundle Size Files Reason
vrml.jbbsrc 88K 2 VRML is a simple, yet frequently encountered format for 3D models. It should be dead simple for jbb to beat it.
animated.jbbsrc 532K 6 These are some animated models with different complexity. They are encoded as THREE.js JSON objects, which is quite fast to parse.
obj.jbbsrc 548K 3 This is a quite big mesh file, in the widely used Wavefont .obj binary format. Looks like a challenging competitor.
heavy.jbbsrcd 3.3M 19 The ben.utf8 and hand.utf8 are two havey meshes encoded in UTF8 format. This is another well-optimised format for storing high-density meshes and another difficult competitor for jbb.
md2.jbbsrc 4.0M 30 This format is used by Quake II to encode animated models. It's a quite optimised file format, both for size and loading time. This also looks like another good competitor.

Size comparison

I used the JBB compiler to load the meshes using their individual loader and to encode them in a .jbb bundle. In addition, I compressed the bundle, since a jbb archive is quite sparse, and it can easily benefit from it. I used GZip compression at maximum level, since we can get it for free from the browser.

To be fair, I also decided to compress the source bundles in order to have a reference value. I compressed each file individually, since this is how the would be served.

The following table summarises the results:

Bundle .jbbsrc Size .jbb Size GZipped .jbbsrc Size GZipped .jbb Size
md2.jbbsrc 4.0M 4.4M 3.9M 3.8M
heavy.jbbsrcd 3.3M 2.2M 2.0M 1.4M
obj.jbbsrc 548K 736K 328K 480K
animated.jbbsrc 532K 404K 260K 268K
vrml.jbbsrc 88K 76K 16K 12K

Size comparison

We can definitely see that the compressed version of .jbb is always smaller than the source files, however that's not always the case when comparing to the compressed version of them.

At least we can see that .jbb is not introducing any penalty for the next tests. So let's have a look at the parsing time next.

Speed comparison

I created a mocha test file that executes the following steps for every bundle:

  • Load the source bundle
  • Encode the javascript structures to a jbb bundle
  • Load the jbb bundle
  • Compare the loading times

The following table illustrates the different loading times:

Bundle .jbbsrc Time .jbb Time
md2.jbbsrc 147ms 103ms
heavy.jbbsrcd 185ms 39ms
obj.jbbsrc 86ms 116ms
animated.jbbsrc 122ms 39ms
vrml.jbbsrc 178ms 155ms

Speed comparison

Here we see something more interesting. Even though in one case jbb loads slightly slower than it's competitor, the overall average loading time of the jbb bundle is 30% to 35% faster.

Not to get excited yet, since this is an ideal scenario on my development machine. Let's see how it behaves in the real world...

A real-world example

Since in a real-world scenario the actual loading time depends both on the data being transferred and the parsing speed, I decided to create a benchmarking website to put the jbb solution in a real test.

I started the measurements from my local installation. As expected, everything seems perfect, since there is no network penalty:

Local Timing

The moment however we switch to a hosted server, we start to see the real performance of the system:

Rawgit Timing

Surprisingly enough, even with one bad case, the average loading time with jbb remains around 30% better.

Conclusions

I have intentionally picked some corner case for the .jbb format, but I might have missed some other real-world scenarios. Nonetheless, with what I observed so far, it looks that .jbb is a quite promising bundling format.

The JBB project has matured during the past year, and it can now even integrate with your gulp pipeline, bringing it one step closer to your project.

Even though more optimisations and new features are still under development, you can already benefit from JBB's performance and bundling convenience! If you are curious, you can start with the JBB and THREE.js tutorial.

I am looking forward to hearing from your experience with jbb. And of course your complaints and objections, since this is a live project!

Github: https://github.com/wavesoft/jbb