前言
Something great
- render :渲染
- Blink: chromium渲染引擎的名称
- parser: 解析器
- AST :(Abstract Syntax Tree,抽象语法树)
- openGL :(Open Graphics Library,开放图形库);一个大部分平台都支持的 底层图形库的 API 标准。
- DirectX:(Direct eXtension,简称DX)微软的多媒体API。
- 沙箱(sandBox):操作系统对 进程的可访问的内存地址所做的限制。
- 渲染进程被 Sandbox 隔离,网页 web 代码内容必须通过 IPC 通道才能与浏览器内核进程通信,通信过程会进行安全的检查。
- 沙箱运行:渲染器在单独的进程中运行,通过沙箱限制其对系统资源(文件、网络、显示、击键)的访问,而须通过父浏览器进程访问
- 插件:浏览器的插件用于显示网页特定内容
- 扩展:浏览器的扩展用于增加浏览器新功能的软件或压缩包
- inspector:(web inspector,调试页面))
第1章 浏览器和浏览器内核
浏览器
-
通常所谓的浏览器内核也就是浏览器所采用的渲染引擎,浏览器内核主要包括以下三个技术分支:排版渲染引擎、 JavaScript引擎,以及其他。
- 渲染引擎决定了浏览器如何显示网页的内容以及页面的格式信息。
- Google V8引擎是一个JavaScript引擎实现,使用C++开发。
-
-
Webkit引擎包含WebCore排版引擎及JavaScriptCore解析引擎。WebCore是苹果公司开发的排版引擎,由排版引擎“KHTML”的基础上而来。 -
Blink是一个由Google和Opera Software开发的浏览器排版引擎,这一渲染引擎是开源引擎WebKit中WebCore组件的一个分支
用户代理和浏览器行为
- 用户代理和浏览器行为体现了客制化,是浏览器的内卷结果。
- 用户代理(User Agent)用于表明浏览器的身份,因而互联网的内容供应商能够知道发送请求的浏览器身份,浏览器能够支持什么样的功能。
- 例如:服务器为Chrome的桌面版和Android版,发送不同的网页内容以适应屏幕和操作系统的差别,或者是因为不同的浏览器支持的标准不一样。
- 这样做的目的当然是为了避免浏览器不支持的功能以及获得更好的用户体验。
- 实践:
- 通过设置用户代理为
chrome -android mobile 刷新后,可以看到页面是为安卓系统设计的,更适合手机交互。
内核特征
- 渲染引擎的功能主要包括:HTML解释器、CSS解释器、布局(lay out)、JS引擎。
- HTML解释器:将HTML文本解释成DOM.
- CSS解释器:为DOM各个元素计算出样式信息,为布局提供基础设施。
- 布局:将DOM元素对象和样式信息结合,计算大小位置等布局信息,形成一个内部表示模型。
- JS引擎:js可以修改网页内容,JS引擎解析js并通过DOM接口和CSSOM接口修改网页内容和样式信息,从而改变渲染结果。
- 绘图:使用图形库,将布局计算后的网页节点绘制成图像结果。
- 渲染引擎依赖了:网络、存储、2D/3D图形、音频和视频、图片解码器。
WebKit与blink
- 2001年WebKit来自KHTML,05年被苹果开源。
- 2013年 blink fork 自WebKit。
第2章 HTML网页和结构
网页构成与结构
- html 是一种半结构化数据表现方式,结构特征有:树状、层次、框结构。
- js代码用于控制网页内部逻辑。即控制用户端逻辑。
- CSS用于描述网页显示信息。
- HTML5 :
- 2D、3D图形以及多媒体方面的支持。使得2D、3D图形以及多媒体 被浏览器原生支持。不需要第三方插件。
- 网页结构:
- 框结构:
- 每个框结构包含一个HTML文档,使用元素嵌套框。桌面端应用较为广泛。
- 层次结构:
WebKit的网页渲染过程
- 网页比我们屏幕可视面积要大,当前可见区域成为视图。
- 渲染分为三个阶段:URL到DOM、DOM到构建绘图上下文、绘图上下文到最终图像
- URL到DOM:
- js可能修改DOM树结构,如步骤7 。
- 节点可能需要依赖其他资源,如图片、CSS、视频等,要异步加载他们,如步骤8 。
- 如果是加载URL,没有标记异步方式,则需要停止DOM构建直到资源加载完。
- 当DOM构建完成时,发出
DOMconent 事件 - 当DOM构建完成、网页所依赖资源都加载完之后,发出
onload 事件。
- 因为资源加载不一定影响DOM树创建,所以这两个事件不一定同时发生。
-
- DOM到绘图上下文:
- webkit 利用CSS和DOM树,构建renderObject树,直到绘图上下文。
- CSS文件被CSS解释器解释成内部表示结构
- CSS解释器结束后,在DOM上附加解释后的样式信息,就是renderObject树
- renderObject 节点创建同时,webkit 根据网页层次结构创建 renderLayer树,同时构建一个虚拟的绘图上下文。
- renderObject树的创建并不会让DOM树销毁,这四个结构一直存在,直到网页被销毁,因为都对网页渲染有很大作用。
-
- 绘图上下文到最终图像:
- 这个过程主要依赖2D、3D图形库。
- 绘图上下文是个与平台无关的抽象类,将每个绘图操作桥接至不同具体绘图实现类。
- 绘图实现类,在chromium 中需要其合成器完成复杂的多进程与GPU加速机制。
- 绘图实现类,将2D、3D图形库绘制的结果保存下来,交给浏览器和UI一起显示。
-
- 如今网页多是动态网页,渲染完成后,由于动画与交互,浏览器一直重复执行渲染过程。
第3章WebKit架构和模块
WebKit架构及模块 及 源代码结构
-
- 主要目录有四个。
- WTF是基础类库,像是C++的 STL库。
- webcore:
- webkit2:
- 主要包含两种类型目录
- 各个进程代码:
- 如 web进程、UI进程、网络进程、插件进程以及它们的共享代码。
- 各移植的简单主函数入口:
基于Blink的Chromium浏览器结构 及 代码结构
-
- content模块和content API,是chromium 对渲染网页功能的抽象。
- 沙箱模型、跨进程GPU硬件加速、众多HTML5功能在content层实现
- content模块和content API 将渲染机制、安全机制、插件机制封装一个接口层。
- 接口层被上层模块使用,内部调用包括了chromium浏览器、content shell,外部包括CEF(chromium enbedded framework)、opera浏览器等。
- chromium浏览器拥有完整功能,但是外壳没开源?
- content shell 是使用content shell包装的简单的壳,用于验证功能有效性和作为开发的demo。
- android 中,开发者大多依赖 content shell 进行移植开发。
- android webview 为了满足android 系统的webview设计,即利用chromium 替换原来的android 默认webview。(这都是历史了吧)
-
多进程模型:
-
chromium常用多进程模型: -
-
- 连接线代表IPC,可以看到NPAPI插件没有定义使用FPU进行加速的接口。
-
多进程模型的好处:
- 避免单个页面的不响应或崩溃影响整个浏览器的稳定性。
- 第三方插件崩溃不影响浏览器稳定性。
- 方便了安全模式的实施,沙箱模型基于多线程。
-
主要进程类型:
- browser 进程:浏览器主进程,负责浏览器界面显示、页面管理,是其他类型进程的祖先,负责他们的创建与销毁。仅有一个。
- renderer 进程: 网页渲染进程,renderer进程数量和网页数量的关系不一定,根据配置改变。沙箱模型启动情况下,该进程会发生变化。
- 插件进程: 每个类型插件创建一次,多个网页使用一种类型插件时,为每个使用者创造一个实例,即插件进程是被共享的。
- GPU进程:最多一个,用于对3D图形加速调用的实现。
-
进程模型特征:
- browser 进程和页面渲染分开,保证页面渲染导致崩溃不影响浏览器主界面崩溃。
- 每个网页独立进程,保证页面互不影响
- 插件进程独立,保证插件问题不影响浏览器主界面和网页。
- GPU硬件加速进程也独立。
-
render 进程创建的类型有:
Process-per-site-instance Process-per-site Process-per-tab Single process -
renderer和 browser进程:
- renderer和 browser进程代码层次如图:
-
- 首先是webkit接口层, 一般基于webkit接口层的浏览器直接在上面构建,不引入复杂的多进程架构。
- 然后是黏附层,是个桥阶层,用于处理chromium和webkit内部的不一致。
- renderer 主要处理进程间的通信,接受来自browser 进程的请求,并调用相应webkit 接口层。
- browser进程 中的 rendererHost 与renderer 对应, 用于处理和renderer 之间的IPC。
- web contents 表示网页内容。
-
多线程模型:
- browser进程:多线程为了保持用户界面的高响应度,保证UI线程对用户操作的响应。
- 主要有主线程、IO线程、还有很多其他线程,用于处理视频、存储、网络、文件、音频、浏览历史等,因为可能这些操作可能阻塞,所以需要置于单独的线程。
- renderer进程: 将渲染过程管线化,利用多核优势。
- 将blink的渲染过程解耦,创建新线程,利用CPU多核能力,加速渲染,像流水线处理一样,提高并发性。
- 网页加载和渲染过程的基本工作方式:
- browser进程收到用户请求,UI线程处理,将任务转给IO线程,然后任务被传递到 renderer 进程。
- renderer进程 的IO线程经过简单解释后交给渲染线程。 渲染线程加载网页并渲染网页,其中可能需要browser进程获取资、需要GPU进程来帮助渲染。 最后renderer 进程将结果通过IO线程传递给browser进程。
- browser进程 将结果绘制出来。
- 线程同步与通信:
- 多线程容易造成死锁、资源竞争与冲突。chromium 使用事件、任务传递机制,仅在不得已时才使用锁或者线程安全对象。
- 线程内部的消息和任务,在第九章 js引擎部分讲解。
-
content 接口:
- 提供了一层对多进程进行渲染的抽象接口。为了支持HTML5功能、GPU硬件加速功能、沙箱机制。
- 相关部分分为:embedder调用的接口、embedder应该实现的回调接口(用于参与具体实现逻辑或事件监听)。
- APP:包括了应用程序或进程的创建与初始化,被所有进程使用,处理一些进程公共操作。
- Browser:HTML5功能等的实现参与,content模块需要调用他们实现HTML5功能;
- Common:一些renderer、browser 共享的公共接口。
- Plugin:通知embedder plugin进程何时被创建的接口类。
- Renderer
- Utility:
-
chromium 代码结构:
- chromiumOS 是一个基于web的OS,仅支持web网页和web 应用程序。
- 还有个很重要的目录:
third_party
- content 目录基本对应了多进程模型中的各种进程类型。
WebKit2 架构、模块
- webkit2 是一套全新结构与接口,同chromium一致,讲渲染过程放在单独进程中,独立于用户界面。
-
- 这里的web进程对应chromium 的rederer进程。UI进程对应chromium 的browser 进程。
- webkit2 和chromium 多进程模型和接口。
- webkit 和chromium 多进程的关系:
-
- renderer进程直接调用webkit 接口。
- content接口允许应用程序注入,并参与content之下各个进程的内部逻辑。
- webkit2 接口希望将多进程结构隐藏,不让应用程序纠缠内部细节。
- webkit 是给 chromium提供content 接口以便构建浏览器,其本身目标不是提供嵌入式接口。
chromium 的渲染
- 渲染:将web content,转换为正确的 openGL 调用,让其显示在屏幕上。
渲染过程
- 样式计算 :渲染进程的主线程解析CSS,确定每个DOM节点的计算样式
- 布局 - layout : 渲染进程知道每个节点的文档结构和样式。布局是查找元素几何的过程。
- 布局过程主线程 遍历DOM并计算样式,并创建布局树(layout tree, 包含坐标和边界框大小等信息)。
确定页面布局的挑战: - 从上到下的块流须考虑字体的大小以及在哪里划分它们,最终影响段落的大小和形状,影响下一段的位置
CSS可以使元素浮动到一侧,屏蔽溢出项,并更改写入方向 - 绘制 - Paint : 主线程遍历布局树以创建绘制记录(知道元素的大小,形状和位置,但是不知道绘制的顺序。)
- 合成 :
- 合成是一种将页面的各个部分分层,分别栅格化,并在合成器线程的单独线程中合成为页面的技术。
- 如果发生滚动,图层已经被栅格化需要合成一个新帧。通过移动图层和合成新帧,可以以相同的方式实现动画。
- 浏览器知道文档的结构、每个元素的样式、页面的几何形状和绘制顺序,需将信息转换为屏幕上的像素,称为光栅化。
- 渲染难点:
- 布局树变化:在每个步骤中,前一个操作的结果用于创建新数据。例如,如果布局树中的某些内容发生更改,则需要为文档的受影响部分重新生成“绘制”顺序。
- 动画:动画对人眼来说会很平滑(视觉停留效应),但是如果动画错过了两者之间的帧或程序运行JS时,则页面将出现卡顿。需要将JS操作划分成小块,并安排在每个帧上运行
渲染步骤
- 渲染的第一步需要解析HTML的标签,生成能反映该HTML结构的对象模型,即DOM(文档对象模型,document object model )。 V8 引擎 通过blindings system 将DOM简单包装后 暴露为:DOM web APIs。
- web content 有 HTML、CSS、JS、video、etc。
- DOM:用于作为页面的内部表示、将查询或修改渲染的API暴露给JS。
-
- V8 引擎 通过blindings system 将DOM简单包装后 暴露为:DOM web APIs
- CSS 的样式属性(style propertys) 是web 开发者用来自定义DOM元素渲染的控制选项(control knob)
-
- 样式属性很多,怎么确定样式作用于哪些元素也越来越复杂,(样式可能被多重规定,可能有冲突)。
-
HTML
- HTML的标签给了文档赋予了语义上的层级结构。
- HTML标签可以嵌套
DOM
- DOM:
- 作为页面的内部表示;
- 作为暴漏给JS 以查询、修改的API;
- V8 引擎 通过blindings system 将DOM简单包装后 暴露为:DOM web APIs。
CSS
- CSS 的selector 选择的就是DOM树的节点,然后将对应的 property 应用于对应节点。
- web 开发者用 properties 定义DOM元素 的渲染。(形变、格式、颜色、边距、位置等)
- 解析CSS 难点在于解析 property具体作用于哪些元素。
浏览器架构
-
整体架构:
- 操作系统:WebKit可以运行在不同的操作系统上,如Chromium浏览器支持Windows、Linux、Android等系统;
- 第三方库:这些库是WebKit运行的基础,包括2D图形库、3D图形库、网络库、存储库、音视频库等;
- WebCore:WebKit加载和渲染网页的基础,是不同浏览器所使用的WebKit中共享的部分,包括HTML解析器、CSS解析器、SVG、布局、渲染树等等;
- JavaScript引擎:JavaScript解析器,WebKit默认的引擎是JavaScriptCore,Google的Blink为V8引擎;
- WebKit Ports:WebKit中的移植部分,包括网络栈、音视频解码、硬件加速等模块,这部分对WebKit的功能和性能影响比较大。
- WebKit嵌入式接口:WebKit对外暴露的接口层,这个接口是提供给浏览器调用的,如给chromium调用,因为接口与具体的移植也有关系,所以中间会有一个WebKit绑定层
-
JavaScriptCore(用于Safari)
- JavaSript Parser,JSON Parser
- 字节编译器:使用内部字节码格式
- 汇编程序:在运行时使用代码修补 - >它需要可写代码内存
- 数据流图:基于编译时推测优化生成代码的新举措
- 解释器:运行生成的字节码
- Regexp引擎:支持JIT
- 垃圾收集器:标记和扫描
- 运行时:所有JS全局对象(日期,字符串,数字等)
- 调试器,Profiler
-
WebCore
- 资源加载器:HTML和XML解析器,DOM
- SVG和SMIL
- CSS:分析器,选择器,动画
- 渲染和布局
- 绑定生成器:IDL文件:JSC,V8,ObjC
- HTML5:音频,视频,画布,WebGL,通知功能
- WebInspector
- 平台集成:图形,字体,声音,视频
浏览器工作原理概述
先后经过页面导航、渲染、资源加载、样式计算、布局、绘制、合成到栅格化,最后完成GPU展示
- 浏览器内核经过了 Loader、Parser、Layout和Paint模块
参考
|