整理自 http://taligarsiel.com/Projects/howbrowserswork1.htm
https://sylvanassun.github.io/2017/10/03/2017-10-03-BrowserCriticalRenderingPath/
浏览器的结构
image.png- browser engine : 查询和操作 rendering engine的接口
- rendering engine: 渲染浏览器请求的内容,比如解析html、css和显示解析后的内容
- networking :网络调用,比如http请求
- UI 后台:画基础组件,比如选项框和窗口。暴露一组接口,底层是操作系统的user interface方法。
- Javascript 解释器: 解析和执行 Javascript代码。
- 数据存: 持久层,浏览器存储各种类型的数据到硬盘上,比如cookies。
Chrome,每个tab是一个进程。
Rendering engines
Firefox :Gecko,Safari 和 Chrome:Webkit
Webkit,最初是Linux平台的rendering 引擎,后来被Apple修改为支持Mac和Windows。
主流程
image.pngWebkit
image.png
Mozilla's Gecko
image.png
解析
生成语法树。
语法
解析器
image.png词法分析: lexer/tokenizer 拆分为有效tokens
语法分析:syntaxanalysis 构建解析树/语法树
解析过程是迭代重复的。
翻译 Translation
翻译成机器语言
image.png
HTML解析器
解析HTML标签,生成解析树
-
不是一个上下文无关语法 Not a context free grammer
与XML的不同,因为HTML很包容,比如可以没有闭合标签。 -
HTML DTD
DTD: Document Type Definition
不同类型的DTD,比如 https://www.w3.org/TR/html4/strict.dtd
- DOM
Document Object Model
HTML的解析树:DOM 元素+ 属性节点。
它是HTML文档的Object presentation。
是HTML元素对外的接口。比如对Javascript。
这棵树的根节点是Document对象。
示例.png- 解析算法
HTML不能按常规的从上往下,或者从下往上的解析。
因为,HTML的容错性;解析过程中,可能会通过JS,document.write 改变tokens。
-
The tokenization 算法
image.png -
Tree construction 算法
image.png
- 解析结束后?
开始解析“deferred”模式的脚本。
document的state设为complete。
load事件开始调用。
CSS 解析
不同于HTML,是context free grammer。
image.png
scripts 解析
处理脚本和样式表的顺序
- Scirpts
The model of web是同步的。阻塞的。
脚本执行会阻塞document解析。
fetch脚本也会阻塞document解析。
defer不会。
HTML5 的 worker会重新开启一个线程解析和执行脚本。
-
Speculative parsing (不知道该怎么翻译)
Webkit和Firefox的一种优化策略。
执行脚本的时候,会并发加载css、js、image等外部资源。(networks) -
样式表
样式表不会改变DOM tree。所以不会阻塞document解析。
但是脚本可以在document解析阶段请求样式信息,如果样式还没加载和执行完成,脚本会出错。
因此,Firefox会在样式表加载执行阶段,阻塞脚本执行。Webkit只会在请求会被样式表影响到的样式属性时才阻塞脚本执行。
构造Render tree
The render tree and the corresponding DOM treeThe initial containing block:Viewport (Firefox)/ RenderView(Webkit)
image.png样式计算
计算每个元素的样式属性。
Firefox为了简单的样式计算,有两个额外的树。Rule tree 和 style context tree。
Webkit 有样式对象,但没有保存在类似style context tree的树里只有dom的节点指向相应的样式。
Firefox rule tree
image.png
style context tree里包含最终的准确的值。比如算出百分比。
The rule tree The context treeGradual process
Webkit会设置一个标记,如果所有顶层样式没有加载完。
一旦样式表加载完,这些dom将重新计算样式。
布局Layout
Render树创建完成之后,需要得到position和size。
计算这些值被称为 Layout或者Reflow。
布局是一个循环的过程,从root开始,
Dirty bit system
页面重写标志位
两个标志:"dirty" 和"children are dirty"
Global and incremental layout
全局:比如resize,global style改变
增量:其他,只有dirty renderers才会重新布局
同步、异步布局
Asynchronous and Synchronous layout
增量的布局是异步的。
Firefox有个scheduler 批处理增量reflow commands。
Webkit有计时器执行。
脚本获取样式信息,比如offsetHeight
会导致同步的reflow。
全局布局通常是同步的。
有些可能是事件的回调会异步。
Painting
display content on the screen
和布局一样,painting也分全局和增量的。
增量:操作系统针对显示器的dirty region
生成paint事件。
Chrome的renderer在一个不同的进程,然后到主进程。
Chorme在一定程度模仿操作系统的行为。
Firefox display list
Firefox会为paint区域先遍历一遍render tree然后创建一个display list。
这样的话,paint过程只用遍历一次。而不是,先所有的背景,然后所有的图片,然后所有的边框,等等。
Webkit rectangle storage
repainting之前,webkit会将老的区域存储为bitmap。
只重绘新老的差别部分。
Dynamic changes
The rendering engine's threads
Rendering 引擎是单线程,几乎所有事情,除了network操作,都在该线程中执行。
在Firefox、Safari中是浏览器的主线程。
在Chrome中是tab进程的主线程。
Network操作是多个线程并行执行的。线程连接总数限制是2-6(不同浏览器不同)
Event loop
浏览器的主线程是个eventloop。
是一个无限的循环。
等待事件(比如layout和paint)和处理事件。
网友评论