持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情
一、浏览器内核—渲染引擎
渲染,就是根据描述或者定义构建数学模型,生成图像的过程。
浏览器内核主要的作用是将页面转变成可视化/可听化的多媒体结果,通常也被称为渲染引擎。将HTML/CSS/JavaScript文本及其他相应的媒体类型资源文件转换成网页。
上图中实线框内模块是所有移植的共有部分,虚线框内不同的厂商可以自己实现。下面进行介绍:
WebCore 是各个浏览器使用的共享部分,包括HTML解析器、CSS解析器、DOM和SVG等。
JavaScriptCore是WebKit的默认引擎,在谷歌系列产品中被替换为V8引擎。
WebKit Ports是WebKit中的非共享部分,由于平台差异、第三方库和需求的不同等原因,不同的移植导致了WebKit不同版本行为不一致,它是不同浏览器性能和功能差异的关键部分。
WebKit嵌入式编程接口,供浏览器调用,与移植密切相关,不同的移植有不同的接口规范。
浏览器内核的层次结构,渲染引擎解析网页资源,调用第三方库进行渲染绘制。
从上面两图可以大概看出渲染引擎的内部组成和大模块。WebCore,负责解析HTML、CSS生成DOM树等渲染进程,js引擎负责解析和执行js逻辑进程。
二、V8 编译与执行
官方图
编辑
那么我们的JavaScript源码是如何被解析(Parse过程)的呢?
1、Blink会将下载好的源码交给V8引擎,Stream获取到源码并进行编码转换
2、Scanner会进行词法分析(lexical analysis),词法分析会将代码转换成tokens
3、接下来tokens会被转换成AST树,经过Parser:
Parser就是直接将tokens转成AST树结构
PreParser称之为预解析,,那为啥要与解析呢?
这是因为并不是所有的JavaScript代码在一开始就会被执行, 如果一开始就对所有的代码进行解析,必然会影响网页的运行效率
所以V8引擎就实现了Lazy Parsing(延迟解析) 的方案,它的作用是将不必要的函数进行预解析,也就是只解析暂时需要的内容,而对函数的全量解析是在函数被调用时才会进行
比如我们在一个函数outer内部定义了另一个函数inner,那么inner函数就会进行预解析
function outer() {
function inner() {
}
}
outer()
像这串代码,当js引擎去执行的时候,inner函数是没有必要转成AST树结构的,因为这串代码压根不运行,但是在执行outer的时候会发现有inner函数,所以会对inner函数进行预解析(提升性能),且inner函数里面的代码不会进行解析