Skip to content
This repository has been archived by the owner on Mar 15, 2018. It is now read-only.

Performance

Matt Basta edited this page Dec 13, 2013 · 2 revisions

One of the benefits of using Commonplace versus any other framework or platform is the flexibility that it provides for writing rich internet applications that are highly performant. When used properly, Commonplace allows you to accomplish this in a sane way.

Performance for the Commonman

There are many aspects to performant rich internet applications (RIAs). On the whole, performance is about time, namely the amount of time taken to appropriately respond to user input. The time required for any action to take place is the result of the efficiency of all code throughout the entire application. It is ideal to minimize time required in virtually every scenario.

Module Performance

Modules should follow some basic performance guidelines:

  • Code should be JITable when possible.
  • Code should create as little garbage as possible.

Respecting the JIT

Highly JITable code is simple to write and provides a solid foundation for other performance improvements. In general, making code JITable involves restricting usage of high-level JS features to allow the engine to perform optimizations behind the scenes. Any code which runs tight loops or is called many times should follow these rules as closely as possible. Some basic examples:

  • Functions should always accept parameters of fixed types. For instance, the a function accepting one argument should never be called with a string in some cases and a number in others. Values of mixed types should always be cast to their expected type.
  • Functions should always return fixed types.
  • Objects--when created with new--should always define their full set of members in the constructor (or prototype. You should never define new members after an object has already been created. Instead, always define the members as null.
  • try blocks prevent their contents from being JITed. Write your code in a function, then wrap a call to that function in a try block instead. This will allow the code to be JITed while still allowing errors to be caught.
  • Avoid code duplication with small functions. If duplicate code exists, one half copy might get JITed while the other copy might not.

These rules aren't hard and fast, but if followed in the majority of cases, they'll make your code noticeably snappier.

Respecting the garbage collector

Garbage is not a problem in browsers powered by V8, but Firefox has issues with memory allocation due to its use of an incremental garbage collector. When you're writing code, treat objects as though every object allocated will take a correspondingly long amount of time to remove from the heap later on.

What makes garbage?

Garbage is created when all references to an object have been removed. For instance:

var foo = {};
foo.bar = "asdf";
foo = null;

After this code runs, there's no longer a reference to the object that foo was initialized to. This will need to be cleaned up by the garbage collector.

You should assume every object you create can and will become garbage, unless it is a primitive type.

Reduce, reuse, and recycle

Garbage can be prevented in a few ways:

  • Don't create it if you don't need to. For example, if you're implementing an algorithm that operates on arrays, try using a variant that modifies arrays in-place rather than creating a temporary one.
  • Don't create objects in tight loops. An occasional temporary object here and there is fine if they're infrequent. If you're about to run a loop, recycle objects instead.
  • Reuse objects rather than creating new ones. Create a temporary object and use it many times rather than creating many objects.
  • Keep objects around if you can reuse them again in the future. If you have a loop that uses a temporary object and you're already reusing the object for each iteration of the loop, you could save one allocation per invocation of the loop by keeping that single object around in a higher scope. This is useful for frequently called functions that create garbage.
  • Cache values if you could reuse some allocated values but not others. It's kind of a compromise: if you can't recycle one object for each iteration of a loop, use a cache to recycle individual allocations.