前言
一探浏览器幕后的《三俩事》上一篇的介绍让大家对浏览器的组成有了个含糊的意识:
- 浏览器是什么?
- 浏览器 (chromium) 根本架构
- 浏览器次要组件
- 浏览器内核是什么?
- JavaScript(js)引擎
- 渲染引擎
明天呢做渲染模块 (WebKit) 开展学习探讨。
首先作为程序介绍来说。我应该具体介绍实现一个浏览器应该蕴含哪些内容 (介绍一下chromium
实现蕴含了哪些内容)。然而思考在 前端
话题的介绍。只做简略的列举不做具体展开讨论; 有趣味能够自行上来学习。
其次按大家耳熟能详的水平来说的话我应该着重讨论一下 JS 引擎(V8 event-loop 相干)
; 然而本节内容还是想先介绍讨论一下 渲染引擎 (WebKit)
。不为别的我就是喜爱玩~ 因为我写这个系列的受众还是偏差前端, 所以波及到须要代码染指解说的局部这边采取JavaScript
来实现。
渲染引擎
画架构图画习惯了, 不要在意俊俏的细节 – -.
由上图能够失去渲染引擎外部解析执行大略过程的信息:
- 当拜访页面的时候会进行网络申请 (network) 去获取页面的内容; 当如果命中缓存 (cache) 就会从存储 (memory) 上间接读取。
- HTMLParser 进行 html 解析通过特定标识进行分块。可解析为 CSS DOM JS 几个模块。
- CSSParser 进行 css 也是解析。
- DOMParser 进行 DOM 构造解析。(构建过程中发现是 JS 局部执行 5, 如果是资源进行异步申请. 不会妨碍解析)。
- JavaScript 局部丢给 JS 引擎进行解析。(如果有操作 DOM/CSS 局部会影响之前的解析, 同时会妨碍解析)。
- 通过上文解析内容构建 RenderTree。
- 解析实现通过 renderTree 进行布局和绘制。
- 将最终图像显示在屏幕上。
上面对于上文所提局部进行展开讨论一下 flow me~ gogogo!
Parser 解析
下面 Parser 的字眼是不是太多了。咱们失去一个信息解析是渲染引擎中十分重要的一个环节,所以首先须要介绍一下解析.
解析文档是指将文档转化成为有意义的构造,也就是可让代码了解和应用的构造。解析失去的后果通常是代表了文档构造的节点树,它称作解析树或者语法树。
解析是以文档所遵循的语法规定(编写文档所用的语言或格局)为根底的。比方说 HTML 解析那么是在 HTML4/ 5 的标准上进行的。所有能够解析的格局都必须对应确定的语法(由词汇和语法规定形成)。
解析过程通常是分成两个子过程:词法剖析和语法分析 。
词法剖析 是将输出内容宰割成大量标记的过程。(进行切分可辨认大量标记的词段)语法分析 是利用语言的语法规定的过程(到底这段语言是要做什么工作)。
HTMLParser
HTML 解析器的工作是将 HTML 标记解析成解析树。
HTML 语法定义:
HTML 的词汇和语法在 W3C 组织创立的标准中进行了定义。
DOM
解析器的输入“解析树”是由 DOM 元素和属性节点形成的树结构。DOM 是文档对象模型 (Document Object Model) 的缩写。它是 HTML
文档的对象示意,同时也是内部内容 (例如 JavaScript) 与 HTML 元素之间的接口。
解析树的根节点是 Document
对象。
DOM 解析 code 示意(不能运行的) 首先要理解解析过程肯定是迭代过程:
// 剖析标记 <> 和属性的正则表达式
var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[\w-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/,
endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/,
attr = /([-A-Za-z0-9_]+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g;
function ParserHTML(html){
// 接管参数 html
while(html){
// 匹配正文内容
if(html.indexOf("<!--") == 0){//}
// 匹配开始标签
if (html.indexOf("<") == 0) {match = html.match(startTag);
if (match) {html = html.substring(match[0].length); // 匹配截取
// 持续迭代
}
}
if(html.indexOf("</") == 0){// 匹配完结标签操作}
}
}
// 输入示意构造
{
element:"",
parentNode:{},
childrenNode:{},
content:"",
....
}
// 我之前写的找不到了 --, 大家能够试着去实现一下。有问题随时沟通 本示例正则可用。
CSSParser
CSS 解析同 HTML 不同中央是上下文无关的语法; 可通过很多解析器做解析。
词法语法(词汇)是针对各个标记用正则表达式定义的:
comment \/\*[^*]*\*+([^/*][^*]*\*+)*\/
num [0-9]+|[0-9]*"."[0-9]+
nonascii [\200-\377]
nmstart [_a-z]|{nonascii}|{escape}
nmchar [_a-z0-9-]|{nonascii}|{escape}
name {nmchar}+
ident {nmstart}{nmchar}*
- 通过 CSS 语法文件主动创立解析器, 会创立自下而上的移位归约解析器。会将 CSS 文件解析成 StyleSheet 对象,且每个对象都蕴含 CSS 规定。CSS 规定对象则蕴含选择器和申明对象,以及其余与 CSS 语法对应的对象。如下:
RenderTree
在 DOM 树构建的同时,浏览器还会构建另一个树结构:渲染树。这是由可视化元素依照其显示程序而组成的树,也是文档的可视化示意。它的作用是让您依照正确的程序绘制内容。
WebKits RenderObject 类是所有渲染树的基类,其定义如下:
class RenderObject{virtual void layout(); // 布局
virtual void paint(PaintInfo); // 绘制
virtual void rect repaintRect(); // 从新绘制 Rect
Node* node; // DOM 节点
RenderStyle* style; // 计算 render style
RenderLayer* containgLayer; //render layer
}
渲染树和 DOM 树的关系
渲染树是和 DOM 元素绝对应的,但并非一一对应。非可视化的 DOM 元素不会插入渲染树中,例如“head”元素。如果元素的 display 属性值为“none”,那么也不会显示在渲染树中(然而 visibility 属性值为“hidden”的元素仍会显示)。
对于多渲染树的例子是格局有效的 HTML。依据 CSS 标准,inline 元素只能蕴含 block 元素或 inline 元素中的一种。如果呈现了混合内容,则应创立匿名的 block 渲染树,以包裹 inline 元素。
有一些渲染对象对应于 DOM 节点,但在树中所在的地位与 DOM 节点不同。浮动定位和相对定位的元素就是这样,它们处于失常的流程之外,搁置在树中的其余中央,并映射到真正的框架,而放在原位的是占位框架。
布局
创立实现渲染树时,并不蕴含地位和大小信息。计算这些值的过程称为布局或重排。
HTML 采纳基于流的布局模型,这意味着大多数状况下只有一次遍历就能计算出几何信息。处于流中靠后地位元素通常不会影响靠前地位元素的几何特色,因而布局能够按从左至右、从上至下的程序遍历文档。然而也有例外情况,比方 HTML 表格的计算就须要不止一次的遍历 (3.5)。
坐标系是绝对于根框架而建设的,应用的是上坐标和左坐标。
布局是一个递归的过程。它从根渲染树(对应于 HTML 文档的 <html> 元素)开始,而后递归遍历局部或所有的框架层次结构,为每一个须要计算的渲染树计算几何信息。
根渲染树的地位左上角 是 0,0
,(跟 canvas2D 坐标规定统一) 其尺寸为视口(也就是浏览器窗口的可见区域)。
所有的渲染树都有一个 layout
或者 reflow
办法,每一个渲染树将会调用其须要进行布局的子代的 layout
办法。
绘制
在绘制阶段,零碎会遍历渲染树,并调用渲染树的 paint
办法,将渲染树的内容显示在屏幕上。绘制工作是应用用户界面根底组件实现的。
绘制的程序其实就是元素进入堆栈款式上下文的程序; 从后向前。块渲染树的堆栈程序如下:
- 背景色彩
- 背景图片
- 边框
- 子代
- 轮廓
绘制实现可参考canvas
(canvas 肯定要学的啊 时刻关注一些前沿的动作
), 理解根底图元绘制办法与过程。例如绘制line
(须要坐标 根底图元构造等等):
图片起源
最初
间隔上一篇文章的生存日记: 20210521 那天呢照样开心(朋友圈仍旧不沉闷)。20210522 呢不开心。20210523 也就是明天总的来说过得去 并没有学习。(劳逸结合 哈哈)
而后呢因为最近有人总微信我编程范式到底抉择哪种好一点呢? 我当初用的更多是什么编程范式呢? 本人写代码保护起来好艰难怎么办呢?… (做了很久的解答, 应该记录下来提供给大家)下期 JS 引擎之前 我会把编程范式做一个简略介绍供大家参考 小小插曲(预计今天)。
加油!有问题请大家随时留言, 看到肯定会回复的。对于上篇补架构图 … 好吧是我鸽了 我看也没人催.. 懒得画了
相干参考
- CSS 的词法和语法
- 解决模型
- WebCore Rendering
- WebKit 官网
- WebKit 介绍
- canvas 相干