V8 powers Chrome and Node.js. Understanding how it compiles and optimizes your code helps you write faster JavaScript.
The Pipeline
Source Code
↓
Parser → AST (Abstract Syntax Tree)
↓
Ignition (Interpreter) → Bytecode
↓ (hot functions)
TurboFan (Compiler) → Optimized Machine Code
↓ (deoptimization if assumptions break)
Back to BytecodeIgnition: The Interpreter
Ignition compiles JavaScript to bytecode quickly. This is the "fast startup" path. Code runs immediately but isn't highly optimized.
TurboFan: The Optimizing Compiler
When a function is called many times (becomes "hot"), TurboFan compiles it to optimized machine code. It makes assumptions based on observed types:
function add(a, b) { return a + b; }
add(1, 2); // V8 sees: integers
add(3, 4); // Still integers
add(5, 6); // TurboFan optimizes for integer addition
add("x", "y"); // DEOPTIMIZATION! String concat is different
// Falls back to bytecode, recompiles laterHidden Classes
V8 creates hidden classes (shapes) for objects. Objects with the same property order share hidden classes, enabling fast property access.
// Good: consistent property order (same hidden class)
function Point(x, y) {
this.x = x;
this.y = y;
}
const p1 = new Point(1, 2);
const p2 = new Point(3, 4);
// p1 and p2 share the same hidden class → fast access
// Bad: inconsistent initialization
const a = {};
a.x = 1;
a.y = 2;
const b = {};
b.y = 2; // Different order!
b.x = 1;
// a and b have DIFFERENT hidden classesInline Caching
V8 caches the location of properties. If an object always has the same shape, property access is as fast as C++ struct access.
// Monomorphic (fastest): always same shape
function getName(obj) { return obj.name; }
// If always called with same hidden class → inline cache hit
// Polymorphic (slower): 2-4 shapes
// V8 handles a few shapes with a lookup table
// Megamorphic (slowest): many shapes
// V8 falls back to dictionary lookupOptimization Tips
- Keep function argument types consistent
- Initialize all properties in constructors
- Don't delete properties — set to undefined instead
- Avoid changing object shapes after creation
- Use TypedArrays for numeric data (Float64Array, Int32Array)
- Small functions inline better — keep functions focused