TurboFan (V8's optimizing compiler) watches functions that run frequently. It observes the types and object shapes passed in, then generates highly specialized machine code assuming those types won't change. When those assumptions are broken, it deoptimizes — throws away the optimized code and falls back to the slower interpreter.
Why this matters: deoptimization isn't free. It costs CPU time and the function runs slower until it gets re-optimized. In hot code paths (scroll handlers, animation loops, data processing), repeated deopts can cause visible jank.
This article covers the most common deopt triggers with before/after examples.
Prerequisites: V8 #1 — JIT Compilation
1. The delete Operator — Changing Object Shape
delete removes a property, altering the hidden class. This deopts any function that assumed the old shape:
Loading editor...
2. The arguments Object — Hidden Side Effects
Using arguments in non-strict mode has magical behavior (it's linked to named parameters). This prevents optimization:
Loading editor...
3. Polymorphic Property Access — Too Many Shapes
Loading editor...
4. try/catch in Hot Functions
try/catch blocks were historically deopt points. Modern V8 has improved this, but try/catch in very hot loops still constrains optimization:
Loading editor...
5. Mixed Types in the Same Variable
V8 optimizes based on observed types. Switching types causes deopt:
Loading editor...
6. Adding Properties After Object Creation
Loading editor...
7. Deopt Pattern Summary
Loading editor...
Key Takeaways
- Deopt means throwing away optimized machine code and restarting in the interpreter — it's expensive.
- The #1 cause: changing object shapes (delete, dynamic property addition, inconsistent construction order).
- The #2 cause: mixed types in the same variable or function parameter.
argumentsobject in non-strict mode is a deopt trap — always use rest parameters.- Most deopt patterns only matter in hot functions (called thousands of times). In cold code, they're harmless.
- Use Chrome's
--trace-deoptflag to see what's deopting in your app.
Next: Patterns #1 — Event Emitter / Pub-Sub — implement on, off, emit, and once from scratch.
