认识浏览器内核
目前较为火爆的浏览器Google Chrome所使用的浏览器内核为Blink,这个内核为webkit的一个分支。
我们经常所说的浏览器内核指的是浏览器的排版引擎:
排版引擎(layout engine),又称为浏览器引擎,页面渲染引擎或样版引擎。
浏览器的工作原理
不知你是否深入思考过,在浏览器输入一个网址后,浏览器会进行哪些工作呢?
首先在输入网址后,浏览器会分析url的结构,然后通过DNS服务器查询域名所对应的IP地址(IP服务器)
然后对这个IP服务器发送请求拿到资源文件index.html
之后浏览器的渲染引擎会对该文件进行解析渲染,主要渲染过程如图
其中HTML文件经过HTMP parser(解析器)解析后生成DOM TREE,CSS 经过 CSS parser解析后生成CSS
规则树(CSS OM),其中紫色框DOM表示js可以操控DOM结构引起DOM Tree的变化,然后DOM Tree与Css
OM 会合并成Render Tree,其中layout是布局引擎,其会根据渲染树在不同浏览器环境下进行一个布
局调整,然后再进行绘制展示到页面上。
那么JavaScript代码由谁执行呢?
JavaScript引擎
因为所有高级编程语言都需转换成机器指令来执行,无论是在浏览器环境还是Node环境,最后都是交由
CPU来执行的,而CPU只认识指令集(机器语言),所以我们需要js引擎来讲js代码翻译成CPU指令来执行。
常见的JavaScript引擎
- SpiderMonkey:第一框js引擎,由js作者开发
- Chakra:微软发布,用于IE浏览器
- JavaScriptCode:webkit中的js引擎,APPle开发
- V8:由Google开发的强大的js引擎,Chromle用的即V8引擎
浏览器内核与Js引擎的关系
浏览器内核主要由两部分组成:
- 1.渲染引擎:负责HTML解析,布局,渲染等工作
- 2.js引擎:负责解析,执行js代码
V8引擎的原理
V8引擎的原理图如下:
V8引擎是由c++编写的,它主要用于Chrome与Node.js等,它可以运行ECMAScript与WebAssembly。
V8引擎拿到js源码后,首先通过解析器(parse)将JavaScript代码转换成AST(抽象语法树),因为解释器
不直接认识js代码。
之后Ignition(一个解释器)会将AST转化成字节码(ByteCode),同时它还会收集TurboFan优化需要信息。
若函数只执行一次,Igintion会直接执行解释字节码。
TurboFan是一个编译器,它可以将字节码编译为CPU可直接执行的机器码;
若一个函数被调用多次,它会被标记为热点函数,就会经过编译器转化成优化后的机器码,从而提高代
码性能。
如果后续执行的代码类型发生变化,机器码也可反向转化成字节码。
V8引擎的解析图(官方)
由浏览器内核Blink将源码交给V8引擎,Stream获取到源码并且进行编码转换;
Scanner会对源码进行词法分析,词法分析会将代码转化成tokens({type:'关键词',value:'name'},
这样的一个对象);
之后tokens经过语法分析后转化成AST树,经过Parser与PreParser,其中PreParser是预解析,进行
预解析的目的是因为并不是所有代码都需要在一开始就执行,所以V8引擎采用Lazy Parsing(延迟解析)
的方案,它的作用是将不必要的函数进行预解析,比如没有调用过的函数。
生成AST树后,会被Ignition转成字节码,之后就是代码的执行过程了。
JavaScript的执行过程
js引擎在执行代码之前,会在堆内存中创建一个全局对象:GO(Global Object)
该对象所有的作用域都可以访问,里面会包含像Dare、Array等,其中还有一个window指向自己(全局对象
window就是这么来的)。
js引擎内部还有一个执行上下文栈(Execution Context Stack,ESC),它是用于执行代码的调用栈,如今
它要执行的是全局的代码块,全局代码块为了执行会创建一个全局执行上下文(Global Execution
Context),GEC会被放入ESC中执行。
GEC中放入到ESC里面的内容有:
- 第一部分:在代码执行前(编译的时候),在parser转换成AST的过程中,会将全局定义的变量,函数加入
到Global
Object中,但并不会赋值(var的变量作用域提升就是这么来的)
- 第二部分:在代码执行中,对变量赋值,或者执行其他的函数
GEC放入到ESC中
© 版权声明
文章版权归作者所有,未经允许请勿转载,侵权请联系 admin@trc20.tw 删除。
THE END