public
Last active

Making Javascript faster

  • Download Gist
making-javascript-faster.md
Markdown

Making Javascript faster

This is a list of guidelines to make your Javascript faster, often associated with jsPerf benchmarks.

Profile before optimizing

If you have an existing codebase, don't get carried away with premature optimizations. Profile to find the slow bits and pick the low hanging fruit.

Some of the latter lessons in Code School's Chrome DevTools course will teach you how to profile your code.

IIFEs vs. nested functions

Seen nested functions like this before?

function doSomething(arg1, arg2) {
  function nestedHelper(arg) {
    return process(arg);
  }

  return nestedHelper(arg1) + nestedHelper(arg2);
}

Unfortunately, every time you run the doSomething function, it recreates the nestedHelper function. Instead, you should do this:

var iife = (function() {
  function privateHelper(arg) {
    var result = process(arg);
    return result;
  }

  return function(arg1, arg2) {
    return privateHelper(arg1) + privateHelper(arg2);
  }
})();

In this case, privateHelper is created only once.

Benchmark: http://jsperf.com/iifes-vs-nested-functions/2

Don't use arguments

As with above, using arguments makes your function variadic, which Javascript engines can't do much about.

Benchmark: http://jsperf.com/how-slow-is-arguments/2

However, don't think that an array parameter is any better (i.e. function(arrayParameter) { ... }). Between iterating arguments vs. an array parameter, arguments is faster.

Benchmark: http://jsperf.com/arguments-vs-array-argument/2

Write shorter functions

If V8 sees that your function is short, it's more likely to be inlined. So don't fear splitting a large function into many smaller functions.

Evidence of optimizations in V8 can be seen by running this benchmark (notice the variation in IIFE running performance).

Link: http://wingolog.org/archives/2011/06/10/v8-is-faster-than-gcc

Put comments outside the function

You should be aware that comments inside your function increase the likelihood it won't get inlined. Strange, but true! I suppose that is the fate of super-optimized VMs.

However, this shouldn't be a problem at all if you minify your code, right? :-)

Link: http://floitsch.blogspot.com.au/2012/03/optimizing-for-v8-inlining.html

Use that instead of bind

It's much faster to create a variable in the outer scope rather than using Function.bind.

// bind - don't do this
function thisFunction() {
  return this.member;
}
var boundFunction = someFunction.bind(this);

// that - do this!
var that = object;
function thatFunction() {
  return that.member;
}

Benchmark: http://jsperf.com/bind-vs-that/3

Don't add new members to constructor instances

TODO

function Point(x, y) {
  this.x = x;
  this.y = y;
}
var p1 = new Point(11, 22);
var p2 = new Point(33, 44);
// At this point, p1 and p2 have a shared hidden class
p2.z = 55;
// warning! p1 and p2 now have different hidden classes!
http://www.html5rocks.com/en/tutorials/speed/v8/

Always initialize object members in the same order

TODO

Source: http://www.html5rocks.com/en/tutorials/speed/v8/

Prefer monomorphic over polymorphic functions

TODO

function add(x, y) {
  return x + y;
}
add(1, 2);      // + in add is monomorphic
add("a", "b");  // + in add becomes polymorphic

Source: http://www.html5rocks.com/en/tutorials/speed/v8/

Avoid using delete

TODO

var o = { x: 1 }; 
delete o.x; // true 
o.x; // undefined

http://coding.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/

Use DocumentFragment

TODO

Web workers

TODO: give example of moving processing to another thread

TODO: Shims?

Use hash lookups instead of testing array presence

TODO

Little wins

Below are some of the other experiments I performed. They weren't included in the above list because the wins are fairly marginal.

No wins

Sources

Uint32Array vs Array is now significantly faster in Chrome. No difference in Firefox, and slower in IE though.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.