Writing Optimized code in JS by understanding Hidden Classes
By: Tooba Ali
Tags: JavaScript, Optimization, Coding, Javascript Tips, Hidden Class

JavaScript, as we know, is a dynamic programming language. What does that mean? Well, in a nutshell, it means that we can add, remove, or modify properties and methods of JS objects at run-time!

With that being a pro to JavaScript’s dynamic nature, there is a con to it too. JS objects are implemented as what is called a HASH TABLE in memory. Hash tables make it much slower to retrieve a property on an object as compared to the contiguous buffer method used in non-dynamic programming languages.

SO WHAT DO WE DO!? Well, the V8 JavaScript engine has got you covered. All you need to do as a developer is to learn about the solution provided by the V8 engine and to adopt coding practices accordingly for writing better-optimized code.

The V8 engine provides the solution by providing a method called Hidden classes. The purpose of hidden classes is to optimize the access time when retrieving a property on an object. This is achieved by sharing hidden classes among objects created in a similar fashion.

Whenever an object is created in JavaScript, a hidden class is attached to it. Whenever a property is added to the object, “class transition” takes place i.e. the old hidden class switches to a new hidden class with the new property in it. Let’s understand this with an example.

function cupcake(frosting,sprinkles) {

this.frosting = frosting;

this.sprinkles = sprinkles;

}

We have a constructor function cupcake that takes as argument the frosting type and the sprinkles type and whenever this function is invoked; we get an object that is our new Cupcake!

When V8 sees our cupcake constructor function is declared, it creates a hidden class say Class0. Now, when V8 sees on line 2, frosting being added as a property on cupcake, it updates the class0 with the new frosting property and switches from class0 to a new hidden class say class1. The same happens when sprinkles are added to the cupcake and class transition occurs from class1 to class2.

Transition of hidden classes

Keeping this in mind, let’s create two cupcakes; chocCupcake and lemonCupcake:

let chocCupake = new cupcake(chocolate, jimmies);

let lemonCupcake = new cupcake(lemon, sandingSugar); //let's add a few more properties to our cupcakes so that they taste even better! chocCupcake.syrup = "chocolate";

choccCupcake.topping = "cookie"; lemonCupcake.topping = "cherry";

lemonCupcake.syrup = "caramel";

Now, adding new properties dynamically to our two cupcakes the way we did above; is a valid solution. BUT this is not an optimized solution! Why? Because the order in which we instantiated the two new properties (namely syrup and topping) is different! A different order results in the creation of two different hidden classes instead of sharing a common hidden class. This is what would happen under the hood:

V8 creates class0 for the constructor function cupcake. It transits to class1 for frosting and then to class2 for sprinkles. For chocCupcake, when it sees a property syrup being added it transits to class3a(class with syrup property) and for topping to class4a(class with topping property). HOWEVER, for lemonCupcake V8 first sees the property topping being added to it and therefore instead of sharing the hidden class class3a, it creates a new hidden class class3b(class with topping property). It then creates a new hidden class for property syrup say class4b(class with syrup property).

Since the two objects do not share the hidden classes (when they could have shared them); the access to the properties of the object is slow because V8 is now not able to make use of inline caching. If the two had shared the hidden class, V8 would have used inline caching for faster access to object properties!

Now that we know how V8 does all the working under the hood, it is important to keep in mind the TWO OPTIMIZATION TECHNIQUES when writing code in JavaScript:

Try to assign all properties of an object in its constructor. If still(for some reason), you are dynamically adding new properties to the objects, always instantiate them in the SAME ORDER so that hidden classes may be shared among them!

Happy Coding! 😄