上一篇,我们介绍了 V8 引擎的执行管道架构。本篇将着重介绍 V8 的语法解析过程。原视频
上一篇是产品经理思维;本篇则是理工科思维;
语法解析阶段对于前端来说尤其重要,相对 Noder 来说较弱,因为 parser 只会影响应用启动和前期的运行阶段。
对于前端同学来说,经常习惯性的引入一些很大的库,而只使用了其中1,2个函数。例如 lodash。这样对性能的影响到底有多大?
还是结论先行
- V8的语法解析有2种模式:eager 解析器(全面)和 lazy 预解析器(快速)。虽然 lazy 解析比 eager 快一倍,但是lazy可能导致需要1.5倍的解析时间;(lazy 预解析后,还需要 eager 解析一次)。你可以用Optimize.js强制 eager 运行
- JavaScript 的语法解析速度为:1MB/S。解析400k JavaScript,需要大概370ms。可以通过 chrome 浏览器地址栏
chrome://tracing
查看具体时间; - 前端页面运行的 JavaScript 代码尽量少;解析器也有缓存,缓存字节码,如果采用 bundle 的话,更新 bundle 会导致整个 bundle 失效。
计算机编译原理简单介绍
由于本篇需要部分计算机编译原理背景知识。所以感觉需要补充一下,计算机编译原理,将人能读懂的代码转换成机器能读懂的代码,机器执行时只认识机器语言指令。
通常计算机高级语言都需要经过:源程序->语法解析->中间代码生成->代码优化->目标代码生成->目标程序。对应V8也不例外:JS源代码->语法解析->生成字节码->编译器->转化器->运行代码。
语法解析阶段生成语法树和作用域,就是将我们的每行代码变成语法树状结构,来消除歧义,代码分析,绑定作用域。
可以通过esprima看看JavaScript的语法树什么样子:http://esprima.org/demo/parse.html#。
本篇主要介绍V8的语法解析过程,产物就是字节码(中间代码)。下一篇介绍V8的编译器运行。