The V8 engine is Google's open-source, high-performance JavaScript engine written in C++. Alongside Google Chrome, it can also be found in MongoDb, Node.js, and many other popular applications.
It’s interesting to explore what makes V8 so fast and which techniques are used to achieve this level of performance.
OOP, design patterns, and performance
Some C/C++ programmers hold the mistaken belief that using OOP and design patterns reduces application performance. V8 is a good example showing that this is not necessarily true. V8 implements many design patterns, and it’s well optimized.
Here are some of the patterns used:
Factory
When the JavaScript engine executes a script, it creates an instance for each variable, function, or array it encounters. JSObject is the parent class of all these kinds of objects.
Here’s a list of all the classes that inherit from JSObject:

V8 implements a factory class to create the required objects, and the Factory::NewJsObject method is used for this purpose.
Here are all the methods that use it:

The factory is not used directly by the V8 classes; it’s invoked from the Heap class, which adds another level of indirection to the implementation.
Visitor
As explained on the Visitor pattern wiki page:
The visitor design pattern is a way of separating an algorithm from an object structure on which it operates. A practical result of this separation is the ability to add new operations to existing object structures without modifying those structures. It is one way to follow the open/closed principle.Like the factory pattern, this pattern also adds some indirection to the implementation, but it makes the code more readable and maintainable.
The V8 source code contains many classes that implement the Visitor pattern.

Even though V8 developers need to optimize execution performance, they are willing to introduce some indirection into the code. It’s true that using design patterns and some C++ mechanisms can impact performance due to the indirection added by their implementation, but that’s more a matter of micro-optimization. Significant macro-level optimization depends more on design choices tailored to your application’s needs.
V8 design choices to optimize its execution
1- Hidden classes and fast property access
JavaScript is a dynamic programming language: properties can be added to, and deleted from, objects on the fly. This means an object’s properties can change over time.
As mentioned before, JSObject is the parent class of JSFunction, which represents a JavaScript function, or JSValue, which represents a JavaScript value. However, there’s no class inheriting from JSObject that represents a class like Function or Value. Most JavaScript engines use a dictionary-like data structure to store object properties; each property access requires a dynamic lookup to resolve the property’s location in memory.
This approach makes accessing properties in JavaScript typically much slower than accessing instance variables in programming languages like Java and Smalltalk. In these languages, instance variables are located at fixed offsets determined by the compiler due to the fixed object layout defined by the object’s class. Access is simply a matter of a memory load or store, often requiring only a single instruction.
V8 uses the concept of hidden classes to reduce the time required to access JavaScript properties. V8 does not use dynamic lookup to access properties. Instead, V8 dynamically creates hidden classes behind the scenes.
2- Dynamic machine code generation
V8 compiles JavaScript source code directly into machine code when it is first executed. There are no intermediate bytecodes and no interpreter. Property access is handled by inline cache code that may be patched with other machine instructions as V8 executes.
3- Efficient garbage collector
V8 reclaims memory used by objects that are no longer required, in a process known as garbage collection. To ensure fast object allocation, short garbage collection pauses, and no memory fragmentation, V8 employs a stop-the-world, generational, accurate garbage collector. This means that V8:
- stops program execution when performing a garbage collection cycle.
- processes only part of the object heap in most garbage collection cycles, which minimizes the impact of stopping the application.
- always knows exactly where all objects and pointers are in memory, which avoids falsely identifying objects as pointers — something that can result in memory leaks.
Conclusion
Choosing not to use OOP and design patterns simply because performance is your top priority may be a bad idea: you might gain a few microseconds but lose the readability and maintainability of your code.
Significant macro-level optimization depends more on design choices tailored to your application’s needs.
