v8的编译和解释
编译器和解释器
- 在编译型语言的编译过程中,编译器首先会一次对源代码进行词法分析、语法分析,生成抽象语法树(AST),然后是优化代码,最后再生成处理器能够理解的机器码。如果编译成功,会生成一个可执行的文件。但如果编译过程中发生了语法或者其他的错误,那么编译型就会抛出异常,最后的二进制文件也不会成功
- 在解释型语言的解释过程中,同样解释器也会对源代码进行词法分析、语法分析,并生成抽象语法树(AST),不过它会基于抽象语法树生成字节码,最后再根据字节码来执行程序、输出结果。
v8执行一段js的过程
- 生成抽象语法树(AST)和执行上下文
- 生成AST第一阶段分词(词法分析),将源码拆成一个个token
拆分成4个token:let myName = "sunrain"
- 关键字: let
- 变量名: myName
- 赋值: =
- 字符串: "sunrain"
- 第二阶段解析(语法分析)吗,将上一步生成的token数据,根据语法规则转为AST。
- 有了AST就会生成该段代码的执行上下文。
- 生成AST第一阶段分词(词法分析),将源码拆成一个个token
- 生成字节码,解释器Ignition根据AST生成字节码,并解释执行字节码
- 一开始v8直接将AST转换为机器码,但是由于chrome在手机上普及,v8需要消耗大量的内存来存放转换后的机器码(机器码占用的空间远高于字节码),所以后来采用现在的方式。
- 字节码是介于AST和机器码之间的一种代码。字节码需要通过解释器将其转换为机器码后才能执行。
- 执行代码
- 解释器Ignition会逐条解释执行。在执行字节码过程中,如果发现有
热点代码
,比如一段代码被重复执行多次,这种就称为热点代码,那么后天的编译器TurboFan就会将该段热点字节码编译为高效的机器码,然后再次执行被优化的代码时,只需要执行编译后的机器码就可以了。
- 解释器Ignition会逐条解释执行。在执行字节码过程中,如果发现有
js的性能优化
将优化的中心聚焦在单次脚本的执行时间和脚本的网络下载上:
- 提升单次脚本的执行速度,避免JavaScript的长任务霸占主线程,这样可以使得页面快速响应交互
- 避免大的内联脚本,因为在解析HTML的过程中,解析和编译也会占用主线程
- 减少JS文件的容量,因为更小的文件会提升下载速度,并且占用更低的内存。