浏览器执行原理、V8引擎

article/2025/11/10 6:16:26

前言

对一个前端而言,思考JS在浏览器中如何被执行非常重要。笔者是通过codewhy的课程进行学习的,首先感谢codewhy。

浏览器的功能

浏览器的主要功能就是向服务器发出请求,在浏览器窗口中展示您选择的网络资源。这里所说的资源一般是指 HTML 文档,也可以是图片或其他的类型。资源的位置由用户使用 URI(统一资源标示符)指定。浏览器解释并显示 HTML ,文件的方式是在 HTML 和 CSS 规范中指的。这些规范由网络标准化组织 W3C(万维网联盟)进行维护。多年以来,各浏览器都没有完全遵从这些规范,同时还在开发自己独有的扩展程序,这给网络开发人员带来了严重的兼容性问题。如今,大多数的浏览器都是或多或少地遵从规范。

来自https://zhuanlan.zhihu.com/p/99777087?utm_source=wechat_session

浏览器执行的过程

输入URL

当我们从网页中输入某一个URL的时候比如www .xxx.com,它会被DNS协议解析成一个具体的ip地址。(找到服务器的地址),此时服务器会给我们返回一个Index.html的网页。
我们看到的也就是那个index.html网页。
随后浏览器便会帮我们来解析这个网页。

解析网页

当浏览器解析网页时,遇到link标签里的css文件它就会向服务器请求并下载css文件。同理,遇到script标签页它也会从服务器里下载js文件。
这样当前浏览器就把js代码下载下来了。这就有一个问题了?谁来帮我们解析js代码呢?怎么执行呢?

了解浏览器内核

其实解析是依靠浏览器内核来完成的。经过浏览器内核就会变成我们用户能看到的网页了。基本上不同的浏览器是由不同内核来组成的,内核也是浏览器的重要组成部分。
常见的浏览器内核:

  1. Trident:IE的内核,也就是国内双核浏览器的内核之一,此内核只能用于Windows平台,且不是开源的。Trident内核一直延续到IE11,IE11的后继者Edge采用了新内核,已经转向Blink了。(早期比如世界之窗什么)
  2. Gecko:Gecko是Netscape6开始采用的内核,后来的Mozilla FireFox (火狐浏览器) 也采用了该内核,Gecko的特点是代码完全公开,因此,其可开发程度很高,全世界的程序员都可以为其编写代码,增加功能。
  3. Webkit:开源内核,苹果基于KHTML开发的内核。它最早被运用在Safari上(苹果的浏览器),曾经的Chrome用的也是Webkeit。
  4. Presto:Opera Software开发的浏览器排版引擎,它是世界公认最快的渲染速度的引擎,Opera7.0开始使用。13年2月后为了减少研发成本,Opera放弃Presto宣布加入谷歌阵营,采用chromium,之后也紧跟Blink的脚步。
  5. Blink:王炸!它是webkit的一个分支,是由Google和Opera Software开发的浏览器排版引擎(基于webkit开发的),2013年4月发布。现在Chrome内核是Blink。目前运用在chrome、edge、opera等浏览器上。
    浏览器内核也被叫做:Layout engine(排版引擎) 等等,社区里有很多叫法。

浏览器渲染的过程


浏览器将css和js文件下载下来以后,就要进行如上图的操作了。

  1. HTML:(一般情况下为index.html)浏览器内核里有个东西叫做HTML Parser,它先将HTML转换为一个DOM树,在这个过程当中如果有编写JS代码,例如
document.createELementById('xxxx')

它也可以对DOM树进行操作。不过作为一门高级语言,CPU是识别不了JS代码的,所以JS代码会由JS引擎来负责解释.(后文我们会聊到这个js引擎)

  1. CSS:CSS代码会被浏览器内核里面的CSS Parser转换为一个样式规则(Style Rules)

HTML与CSS相结合,会形成一个RenderTree(渲染树),有了渲染树以后,再将渲染树交给Layout(布局引擎),将页面做布局自适应化。形成最终的RenderTree.

完成上述操作,经过浏览器绘制并展示,用户就能浏览页面,并做相关操作了。

这里有个问题?大量的js代码也需要被执行,那它由谁来执行呢?

Javascript引擎

认识JS引擎

实际上我们编写的JS代码,无论我们把它交给浏览器还是Node,最后其实都是cpu来执行的。

可是CPU是无法直接识别高级语言的。在计算机里所有的高级语言都需要转换为机器语言(二进制那种01010101的代码)才能被CPU识别。JS引擎就是帮助我们将JS代码翻译成CPU所能认识的机器语言的。

常见的JS引擎

image.png
(来自https://www.cnblogs.com/guanguan-/p/9771515.html)

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

浏览器的内核是指支持浏览器运行的最核心的程序,分为两个部分的,一是渲染引擎,另一个是JS引擎。渲染引擎在不同的浏览器中也不是都相同的。

  1. 渲染引擎:他负责解析HTML,布局,渲染等工作……
  2. JS引擎:解析并且执行JS代码

V8引擎

上面的JS引擎很多,我们重点关注V8这个引擎。它是由谷歌开发的。

V8引擎V8使用C++开发,并在谷歌浏览器中使用。在运行JavaScript之前,相比其它的JavaScript的引擎转换成字节码或解释执行,V8将其编译成原生机器码(IA-32, x86-64, ARM, or MIPS CPUs),并且使用了如内联缓存(inline caching)等方法来提高性能。有了这些功能,JavaScript程序在V8引擎下的运行速度媲美二进制程序。(来自百度百科)

V8可以独立运行,也可以嵌入到任何C++ 应用程序当中。

很有意思,V8这个引擎的名字其实是来自于超跑品牌保时捷。给它命名为V8足以见得谷歌公司对这个引擎多么自信!而V8也确实是现在最快的浏览器引擎,很多人选择chrome浏览器也是这个原因。

V8引擎的底层原理图:

  1. 第一步,JS代码会经过parse功能模块。(解析,解析其实包括词法分析和语法分析)分析完了,会将其生成为AST抽象语法树。这里给大家提供了一个AST语法树转换网站 ,AST语法树在babel里也有被使用,学过vue的小伙伴应该很亲切。通过AST我们可以将ES6代码转换为ES5代码,也可以转换为字节码(通过ignition功能模块)

为什么一定要转换为字节码而不是机器指令?那是因为不同CPU架构,机器指令是不同的,而字节码是跨平台的,它就方便多了。

  1. 为了更加的优化,我们可以转换一些用的比较多的函数为字节码,也是上面图片的一个模块功能TurboFan,热函数功能。他可以将一些用的比较多的函数标记为热函数。方便提高效率。
    但是我们可以看下面的代码
function sum(n1,n2){n1 + n2
}
sum(20,30) //1
sum('aaa','bbb') //2

由于js是个动态语言,没有做类型限制,我们本想做一个数值的相加(并将其标记为热函数),可是阴差阳错,做成了字符串的拼接)(代码中标记为2处)。那咋解决呢?这个热函数是不是就不能用了呢?当然不是!引擎V8有个Deoptimization功能,它可以再将这种特殊情况转换为字节码。(其实就是处理一个特殊情况)。

由此我们可以推出,若使用Typescript开发,运行效率就会提高不少。

V8引擎是采用C++代码开发的,用了超过100W行的C++代码。

官方V8引擎的解析图

image.png

过程跟我们上述的流程基本上差不多。
要了解的是,内核(blink)会将我们的js代码以流的方式传递给V8引擎。然后将代码的编码传入Scanner转换器、后续操作跟上文描述的基本上差不多。

我们要注意到这个Preparser(预解析)
为什么我们需要预解析?举个栗子

function eat(){function eatFood(){.... //代码片段} 
}
eat()

我们看上面的函数,其实完全没有必要对eatFood那个方法进行解析。因为我们没有调用过它。如果每次都要对它转换成AST,bytecode真的很浪费性能!

所以V8会采用一个Preparser(预解析)功能,以此来提高性能。(引擎只需要知道有这个函数就行了,不需要阅读它里面具体的代码片段)

这有点类似于C语言里面的函数声明。他有个专有名词叫做Lazy Parsing(延迟解析)方案

这些是一些理论的部分,后续我也会结合代码,介绍具体一个代码的运行过程。

通过代码来描述

我们不采用ES6语法,使用var来定义变量。

var name = "name"
var num1 = 20
var num2 = 30
var result = num1 + num2

这段代码在V8引擎中运行的时候到底发生了什么样的过程?

  1. 代码被解析时(从JS代码到AST抽象语法树的过程),V8引擎会帮我们创建一个对象名为GlobalObject。它会包含我们很多的全局对象,比如一些包装类(Math,String,Date…),setTimeout;window属性。要注意解析的时候,V8也会将上述代码的变量(name,num1,num2),写进这个GlobalObject,值为undefined 4.

  2. 运行代码!为了运行代码,V8内部有一个执行上下文栈(Excution context Stack)。并且为了执行全局代码,V8还要创建全局执行上下文(Global context Stack)将它放入执行上下文栈中。
    全局执行上下文中维护了一个东西名为VO,它维护了全局对象GO(GlobalObject),所有要准备的东西都准备好了,就可以开始执行代码了。

var name = "why"
var num1 = 20
console.log(num2); //A处,这个代码的值是undefined
var num2 = 30
var result = num1 + num2

这里我们在A处打印num2,会发现结果为undefined(不是null,不会说找不到)。这很好理解,因为在GO中num2这个变量已经给它赋值成了undefined。

这就是我们经常说的作用域提升(将变量放到GO里面),当我们没给GO里的变量赋值的时候打印,它的结果是undefined。

转自本人掘金


http://chatgpt.dhexx.cn/article/pSR2liQi.shtml

相关文章

ARM v8 简介

ARMv8 Exception Level 在介绍其他概念前,先要了解 ARMv8 全新的异常级设计。 ARMv8 定义了4个异常级。EL0-EL3,数字越大,权限越高。其中 EL0 用于应用程序,EL1 用于操作系统,EL2 用于虚拟化,EL3 用于安全…

V8引擎解析JavaScript原理

为什么需要JavaScript引擎呢? 高级的编程语言都是需要转成最终的机器指令执行的 我们编写的JavaScript无论交给浏览器和Node执行,最后都是被CPU执行的 CPU只认识自己的指令集,实际上是机器语言,才可以被CPU所执行 所以需要借助Jav…

V8引擎详解(一)——概述

背景 在现有的javascript引擎中,V8引擎绝对是其中的佼佼者,chrome和node底层都使用了V8引擎,其中chrome的市场占有率已经达到70%,而node更是前端工程化以及扩展边界的核心支柱,V8引擎对于一个前端开发工程师来说重要程…

浏览器工作原理和V8引擎

一、浏览器的工作原理 比如在浏览器中输入网址,然后dns进行解析,解析出的就是服务器的一个ip地址。服务器返回一个html文件,浏览器内核在解析html文件的过程中,遇到link标签和script标签引用的css文件和JavaScript文件就会去下载…

V8引擎学习

计算机模型 寄存器 中央处理器的组成部分寄存器是有限存储容量额高速存储部件可以用来暂存指令,数据和地址存储器内的数据可以用来执行算术和逻辑运算。寄存器内的地址可用于指向内存的某个位置 内存 随机存取存储器也叫内存,英文缩写RAMRAM是与CPU直…

V8垃圾回收

来自李兵老师的《浏览器工作原理与实践》,太赞了 垃圾回收 内存空间栈空间和堆空间不同语言的垃圾回收策略调用栈中的数据是如何回收的堆中的数据是如何回收的副垃圾回收器主垃圾回收器总结 在我们说V8垃圾回收之前,先讲讲 数据是如何存储的?…

认识V8引擎

1、前言 编程语言一般分为两类,解释性语言和编译性语言。编译型语言在执行之前要先进行完全编译,而解释型语言一边编译一边执行,很明显编译型语言会比解释性语言快,而JavaScript就是一种解释型脚本语言,支持动态类型、…

V8引擎执行原理

v8是C编写的Google开源高性能JavaScript和WebAssembly引擎,它用于Chrome和Node.js等。 它实现ECMAScript和WebAssembly。 v8可独立运行,也可嵌入到任何C应用程序中。 parse模块 parse模块会将JavaScript代码转换成AST(抽象语法树),因为…

Google V8引擎浅析

前端开发人员都会遇到一个流行词:V8。它的流行程度很大一部分是因为它将JavaScript的性能提升到了一个新的水平。是的,V8很快。但它是如何发挥它的魔力? 前言 源代码:https://source.chromium.org/chromium/chromium/src//master:…

js中v8引擎的详解-看的吐血

v8引擎出现的原因 这里先说一下什么是编译型语言和解释性语言: 编译型语言: 在程序执行之前必须进行专门的编译过程,有如下特点: 只须编译一次就可以把源代码编译成机器语言,后面的执行无须重新编译,直接…

Google V8 引擎

V8的前世今生 V8是JavaScript渲染引擎,第一个版本随着Chrome的发布而发布(具体时间为2008年9月2日)。在运行JavaScript之前,相比其它的JavaScript的引擎转换成字节码或解释执行,V8将其编译成原生机器码(IA-32, x86-64, ARM, or M…

编译v8引擎

本机环境是win7vs2010(本来想用2012的,但是发现默认的项目是2010的) 1、首先下载V8的源码 安装好svn,并在cmd下能使用svn help: svn下载地址(安装包):http://download.csdn.net/detail/zengraoli/5651551 …

JavaScript引擎—V8引擎

为什么需要Javascript引擎? 随着JS承担的工作越来越多,早就已超越创造出的初衷(表单验证)的范畴,因此需要快速的解析和执行JavaScript脚本 V8引擎由此而生 JavaScript引擎主要功能:结合JS语言特性 和 本质 …

LVGL V8

本文适用于LVGL V8版本 LVGL simulator vs2019 官方工程 lv_sim_visual_studio 使用注意事项: 1、将官方工程从github上下载下来,最好使用git 将整个工程clone下来,因为工程内部有依赖,如果只是将工程Download下来,无…

为什么V8引擎这么快?

转载请注明出处:http://blog.csdn.net/horkychen Google研发的V8 JavaScript引擎性能优异。我们请熟悉内部程序实现的作者依源代码来看看V8是如何加速的。 作者:Community Engine公司研发部研发工程师Hajime Morita Google的Chrome中的V8 JavaScript引擎&#xff0…

垃圾回收机制之v8引擎

v8的内存分配 (栈(执行环境)跟堆) 堆内存负责垃圾回收机制,只有新生代和老生代两部分 新生代:对等分的(严格) 老生代: 都是由新生代转变的(连续的空间&…

V8 JavaScript引擎

简介 V8 (v8.dev)是 Google 的开源高性能 JavaScript 和 WebAssembly 引擎,用 C 编写。它用于 Chrome 和 Node.js 等。它实现了 ECMAScript 和 WebAssembly,并运行在 Windows 7 或更高版本、macOS 10.12 以及使用 x64、IA-32、ARM 或 MIPS 处理器的 Lin…

V8、JSCore、Hermes、QuickJS,hybrid开发JS引擎怎么选

📌 如果你喜欢我写的文章,可以把我的公众号设为星标 🌟,这样每次有更新就可以及时推送给你啦 在一般的移动端开发场景中,每次更新应用功能都是通过 Native 语言开发并通过应用市场版本分发来实现的。 但是市场瞬息万变…

v8引擎详解

前言 JavaScript绝对是最火的编程语言之一,一直具有很大的用户群,随着在服务端的使用(NodeJs),更是爆发了极强的生命力。编程语言分为编译型语言和解释型语言两类,编译型语言在执行之前要先进行完全编译&am…

Chrome V8引擎介绍

随着Web相关技术的发展,JavaScript所要承担的工作也越来越多,早就超越了“表单验证”的范畴,这就更需要快速的解析和执行JavaScript脚本。V8引擎就是为解决这一问题而生,在node中也是采用该引擎来解析JavaScript。V8是如何使得Jav…