浏览器内核和JS引擎的关系?为什么V8在JS引擎中独领风骚?讲讲你不知道的V8中JS的执行原理

javascript—002-运行原理02—浏览器渲染过程、认识JS引擎、浏览器内核与JS引擎的关系、V8引擎的原理、V8引擎的核心模块

学习浏览器的内部工作原理将有助于作出更明智的决策,并理解那些最佳开发实践的各种缘由

上一篇博客聊到:
在这里插入图片描述
上一篇博客说到过:微软的Edge已经不像IE一样,不再使用Trident内核了,改用Blink内核,因为最近装了Win10虚拟机,所以我特地去查看了我一下我虚拟机上Edge的浏览器内核:

查看Edge内核步骤:
(1)“…”—>设置
在这里插入图片描述
(2)左侧菜单栏选择“关于Microsoft Edge”:
在这里插入图片描述
(3)看到其实Edge基于Chromium开发的
在这里插入图片描述
Chromium是什么呢?
在这里插入图片描述

再整理一下关于浏览器内核的知识:
在这里插入图片描述

以前端的立场来说,当然是希望Blink内核可以一统江湖,因为这样敲代码的时候就不用考虑这么多兼容性了

还要注意,在不同的社区,内核有不同的叫法。内核=排版引擎=页面渲染引擎=样板引擎

一、浏览器渲染过程

拿图说话:

谁解析javascript代码?---->JS引擎

下面就来说明JS引擎如何解释JS代码的

二、认识Javascript引擎

为什么需要JS引擎?
1.高级的编程语言都是需要转成最终的机器指令来执行的:
在这里插入图片描述

2.事实上对于JavaScript代码,无论交给浏览器或者Node执行,最后都是需要被CPU执行的:
在这里插入图片描述
3.但是CPU只认识自己的指令集,实际上是机器语言,才能被CPU所执行
在这里插入图片描述
4.所以需要JavaScript引擎将JavaScript代码翻译成CPU指令来执行
在这里插入图片描述
很多人都知道有哪些浏览器内核,但是又有哪些javascript引擎呢?
在这里插入图片描述

三、浏览器内核与JS引擎的关系?

举个有代表性的例子:
(摘自百度百科)
在这里插入图片描述

在这里插入图片描述

四、V8引擎

V8引擎的 原理:

V8是用C ++编写的Google开源高性能 JavaScriptWebAssembly引擎,它用于ChromeNode.js等。
它实现ECMAScript和WebAssembly,并在Windows 7或更高版本,macOS 10.12+和使用x64,IA-32, ARM或MIPS处理器的Linux系统上运行。-------->跨平台!!
V8可以独立运行,也可以嵌入到任何C ++应用程序中。

运行原理图:(其实我自己学过一点点编译原理,这张图还是比较好理解的)
在这里插入图片描述
AST:abstract syntax tree,抽象语法树,a set of objects that represent the program structure(一个展示程序集合的对象集合)

**V8’s parser consumes ‘tokens’ provided by the scanner. **
V8的parser会利用由“scanner”提供的tokens

Tokens are blocks of one or more characters that have a single semantic meaning: a string, an identifier, an operator like ++.
标记是由一个或多个具有单一语义的字符组成的块:一个字符串、一个标识符、一个类似++的运算符等等。

The scanner constructs these tokens by combining consecutive characters in an underlying character stream.
Scanner通过组合基础字符流中的连续字符来构造这些标记。

The scanner consumes a stream of Unicode characters. These Unicode characters are always decoded from a stream of UTF-16 code units. Only a single encoding is supported to avoid branching or specializing the scanner and parser for various encodings, and we chose UTF-16 since that’s the encoding of JavaScript strings, and source positions need to be provided relative to that encoding. The UTF16CharacterStream provides a (possibly buffered) UTF-16 view over the underlying Latin1, UTF-8, or UTF-16 encoding that V8 receives from Chrome, which Chrome in turn received from the network. In addition to supporting more than one encoding, the separation between scanner and character stream allows V8 to transparently scan as if the entire source is available, even though we may only have received a portion of the data over the network so far.
Scanner使用Unicode字符流。这些Unicode字符总是从UTF-16代码单元流中解码。只支持一种编码,以避免对各种编码进行分支或专门化扫描器和解析器,我们选择UTF-16,因为这是JavaScript字符串的编码,并且需要提供相对于该编码的源位置。UTF16CharacterStream在V8从Chrome接收的底层拉丁1、UTF-8或UTF-16编码上提供了一个(可能是缓冲的)UTF-16视图,而Chrome又从网络接收这些编码。除了支持多种编码之外,扫描仪和字符流之间的分离允许V8透明地扫描,就好像整个源代码都可用一样,即使到目前为止我们可能只通过网络接收到部分数据。

V8引擎的架构

V8引擎本身的源码非常复杂,大概有超过100w行C++代码(其实一般的操作系统源码是它的十倍左右,所以没有必要看V8的源码),通过了解它的架构,我们可以知道它是如何对JavaScript执行的:
查看V8源代码:https://github.com/v8/v8
在这里插入图片描述

Parse

会将JavaScript代码转换成AST(抽象语法树),这是因为解释器并不直接认识JavaScript代码;
如果函数没有被调用,那么是不会被转换成AST的;
Parse的V8官方文档:https://v8.dev/blog/scanner
在这里插入图片描述

提供一个ast抽象语法树的相关网站:https://astexplorer.net
在这里插入图片描述
在这里插入图片描述

Ignition

在这里插入图片描述

是一个解释器,会将AST转换成ByteCode(字节码)
同时会收集TurboFan优化所需要的信息(比如函数参数的类型信息,有了类型才能进行真实的运算);
如果函数只调用一次,Ignition会执行解释执行ByteCode;
Ignition的V8官方文档:https://v8.dev/blog/ignition-interpreter

TurboFan

是一个编译器,可以将字节码编译为CPU可以直接执行的机器码;
如果一个函数被多次调用,那么就会被标记为热点函数(hot),那么就会经过TurboFan转换成优化的机器码,提高代码的执行性能;
但是,机器码实际上也会被还原为ByteCode,这是因为如果后续执行函数的过程中,类型发生了变化(比如sum函数原来执行的是
number类型,后来执行变成了string类型),之前优化的机器码并不能正确的处理运算,就会逆向的转换成字节码;----->这里也可以看出为什么TS执行速度比JS快了
TurboFan的V8官方文档:https://v8.dev/blog/turbofan-jit

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值