V8 引擎是怎么让 JS 跑这么快的?
本文最后更新于:2026年2月12日 凌晨
V8 引擎是怎么让 JS 跑这么快的?
V8 是 Google 开发的开源 JavaScript 引擎,用 C++ 写的,Chrome 浏览器和 Node.js 都用它。它打破了”解释型语言执行慢”的固有印象,让 JavaScript 的运行速度能跟原生机器码掰掰手腕。
浏览器里的位置
在深入 V8 之前,先了解下它在浏览器里的位置。浏览器有两个核心引擎:
- 渲染引擎(WebKit、Blink 这些):负责解析 HTML/CSS,构建 DOM 树和渲染页面
- JavaScript 引擎(V8、JavaScriptCore 这些):负责解析执行 JS 代码

V8 的执行流程
早期 V8 直接把 AST 编译成机器码,执行确实快,但内存占用爆炸。现代 V8 引入了 Ignition 解释器 和 TurboFan 优化编译器 的组合架构。
1. 解析(Parsing)
源码先经过词法分析和语法分析,转成 抽象语法树(AST)。

2. 解释执行(Ignition)
Ignition 把 AST 转成字节码(Bytecode)。字节码介于源码和机器码之间,内存占用更小,启动更快。
3. 优化编译(TurboFan)
代码跑起来的时候,V8 会收集运行信息(Profiling)。如果某个函数被频繁调用(热点代码),TurboFan 就会把它编译成高度优化的机器码。
4. 去优化(Deoptimization)
JavaScript 是动态类型的。如果优化后的机器码假设变量是 int,结果运行时变成了 string,V8 会立即”去优化”,退回到字节码执行。
核心优化技术
1. 隐藏类(Hidden Class)
C++ 这些静态语言通过偏移量查找属性,很快;JS 默认通过字符串哈希查找,慢得要死。V8 会给对象创建”隐藏类”,存储属性的内存偏移量。
1 | |
建议:在构造函数里一次性声明所有属性,别随便动态添加/删除属性,否则会破坏隐藏类共享。
2. 内联缓存(Inline Cache)
V8 会缓存最近一次属性查找的结果。如果下次访问的对象隐藏类没变,直接用缓存地址,不用再查一遍。
内存管理与垃圾回收(GC)
V8 把堆内存分为新生代和老生代。
1. 新生代(Young Generation)
- 特点:放存活时间短的对象
- 算法:Scavenge 算法。内存分 From 和 To 两块,回收时把 From 里的存活对象复制到 To,然后清空 From
- 晋升:经历过两次 GC 还活着的对象移到老生代
2. 老生代(Old Generation)
- 特点:放常驻内存或体积大的对象
- 算法:Mark-Sweep(标记清除)和 Mark-Compact(标记整理)
- 优化:增量标记(Incremental Marking),把标记过程拆成小步,穿插在 JS 执行间隙,避免长时间的”全停顿”(Stop-The-World)

怎么写出 V8 喜欢的代码?
- 固定属性顺序:以相同顺序初始化对象属性,保证隐藏类一致
- 避免”类数组”操作:尽量用真正的数组,数组里放相同类型的数据性能最高
- 保持函数类型稳定:别给同一个参数传不同类型的数据(一会儿数字一会儿字符串)
- 及时释放内存:不再需要的全局变量手动设为
null,避免闭包导致的内存泄漏
总结
V8 的强大在于它对动态特性的极致静态化处理。通过字节码平衡内存、通过热点探测编译机器码优化、通过隐藏类加速属性访问,它让 JavaScript 具备了支撑复杂后端应用(Node.js)和超大型前端应用的能力。