V8 Engine
HardV8 is the JavaScript engine powering Chrome and Node.js. It compiles JavaScript to machine code using a two-tier approach: Ignition (interpreter) for quick startup, and TurboFan (JIT compiler) for hot code optimization.
Interactive Visualization
CodeIdle
1function add(a, b) {2 return a + b;3}45// First call: Interpreted6add(1, 2);78// Many calls: Gets optimized!9for (let i = 0; i < 1000; i++) {10 add(i, i);11}
V8 Pipeline
Source
function add(a, b) {...}
Parser
...
AST
...
Ignition
...
TurboFan
...
V8 receives your JavaScript source code
1 / 8
Key Insight: V8 uses two compilers: Ignition (fast startup) and TurboFan (fast execution). Hot code gets optimized!
Key Points
- Parser converts source code to Abstract Syntax Tree (AST)
- Ignition: interpreter that generates bytecode for fast startup
- TurboFan: JIT compiler that optimizes "hot" frequently-run code
- Hidden Classes: V8 creates shapes for objects to optimize property access
- Inline Caching: remembers where to find properties on repeated access
- Deoptimization: falls back to interpreter when assumptions break
Code Examples
Compilation Pipeline
// Your code goes through: // 1. Parser → AST // 2. Ignition → Bytecode // 3. (If hot) TurboFan → Machine Code function add(a, b) { return a + b; } // Called once: interpreted add(1, 2); // Called 1000x: JIT compiled! for (let i = 0; i < 1000; i++) { add(i, i); }
Hot functions get JIT compiled for speed
Hidden Classes
// V8 creates hidden classes for shapes function Point(x, y) { this.x = x; // Hidden class C0 → C1 this.y = y; // Hidden class C1 → C2 } // Same shape = same hidden class let p1 = new Point(1, 2); let p2 = new Point(3, 4); // p1 and p2 share hidden class! // Fast property access
Same property order = same hidden class
Breaking Hidden Classes
function Point(x, y) { this.x = x; this.y = y; } let p1 = new Point(1, 2); let p2 = new Point(3, 4); // BAD: Adding property breaks class p1.z = 5; // p1 gets new hidden class // Now p1 and p2 have DIFFERENT // hidden classes = slower access
Adding properties creates new hidden classes
Monomorphic Calls
// FAST: Always same type (monomorphic) function getX(point) { return point.x; } let p = { x: 1, y: 2 }; for (let i = 0; i < 1000; i++) { getX(p); // Same shape every time } // SLOW: Different types (polymorphic) getX({ x: 1 }); getX({ x: 1, y: 2 }); getX({ x: 1, y: 2, z: 3 });
Consistent object shapes enable optimization
Deoptimization
function add(a, b) { return a + b; } // V8 optimizes for numbers for (let i = 0; i < 10000; i++) { add(i, i); // TurboFan optimizes } // Type change triggers deopt! add("hello", "world"); // V8 must deoptimize and // recompile with new assumptions
Changing types causes deoptimization
Optimization Tips
// 1. Initialize all properties in constructor function User(name, age) { this.name = name; this.age = age; this.email = null; // Even if null! } // 2. Keep types consistent function process(x) { return x * 2; // Always pass numbers! } // 3. Avoid delete (breaks hidden class) user.email = undefined; // Better // delete user.email; // Slower
Tips for V8-friendly code
Common Mistakes
- Adding properties to objects after creation (breaks hidden classes)
- Passing different types to the same function (polymorphic = slow)
- Using delete instead of setting to undefined
- Premature optimization without measuring
Interview Tips
- Explain the difference between interpreter and JIT compiler
- Know why consistent object shapes matter for performance
- Understand when deoptimization happens
- Be able to discuss hidden classes and inline caching