网上找了些资料,记录下博客连接
How Browsers Work: Behind the scenes of modern web browsers
https://mp.weixin.qq.com/s/Lp8XDZlTFBRG2vUKwSo0mA
浏览器运行机制
回流、重绘
关键渲染路径
学习笔记。
请参看分享的文章先。
# 浏览器信息部分
记录点 1 主流浏览器有五个:Internet Explorer、Firefox、Safari、Chrome 浏览器和 Opera。
浏览器使用情况统计:StatCounter 浏览器统计数据
呈现引擎:Firefox 使用的是 Gecko,这是 Mozilla 公司“自制”的呈现引擎。而 Safari 和 Chrome 浏览器使用的都是 WebKit。
呈现引擎的基本流程:文本->dom Tree -> render Tree -> layout -> paint -> 页面显示 。
# 浏览器处理脚本和样式表的顺序
记录点 2 解析器遇到 <script> 标记时立即解析并执行脚本。
如下代码:
// index.js
alert(document.getElementById('div'))
<!-- index.html -->
<body>
<script src="./js/index.js"></script>
<div id="div"></div>
</body>
上述代码在运行时,alert结果为null,因为script标签写在了前面。
运行结果:
![]()
该场景的解决方法:
- script 标签添加 defer 属性,这样可以并行加载,在DOMContentLoaded 事件中执行;
- 将script 标签放在body 底部。
![]()
记录点 3 Firefox 在样式表加载和解析的过程中,会禁止所有脚本。而对于 WebKit 而言,仅当脚本尝试访问的样式属性可能受尚未加载的样式表影响时,它才会禁止该脚本。
原因:存在这样一问题,脚本在解析执行时可能会去获取样式信息,此时如果脚本和样式的处理完全并行,那么脚本有可能获取到错误的信息。
记录点 4 呈现器(呈现树的节点)是和 DOM 元素相对应的,但并非一一对应。
- 非可视化元素不会插入呈现树,例如head、meta等;
- display:none; 的元素也不会插入到呈现树(但visibility 属性值为“hidden”的元素仍会显示);
- dom中的一个节点可能对应多个呈现树节点,例如,“select”元素有 3 个呈现器:一个用于显示区域,一个用于下拉列表框,还有一个用于按钮。
- 有一些呈现对象对应于 DOM 节点,但在树中所在的位置与 DOM 节点不同。
记录点 5 呈现器在创建完成并插入到呈现树中时,是不包含位置和大小信息的。计算这些值的过程称为布局或重排(reflow)。
- 布局是一个递归的过程。它从根呈现器(对应于 HTML 文档的 元素)开始,然后递归遍历部分或所有的框架层次结构,为每一个需要计算的呈现器计算几何信息。
- 所有的呈现器都有一个“layout”或者“reflow”方法,每一个呈现器都会调用其需要进行布局的子代的 layout 方法。
全局布局和增量布局
全局布局是指触发了整个呈现树范围的布局,触发原因可能包括:
- 影响所有呈现器的全局样式更改,例如字体大小更改。
- 屏幕大小调整。
增量布局是异步执行的。全局布局往往是同步触发的。(这里待理解消化)
布局处理
布局通常具有以下模式:
- 父呈现器确定自己的宽度。
- 父呈现器依次处理子呈现器,并且:
1. 放置子呈现器(设置 x,y 坐标)。
2. 如果有必要,调用子呈现器的布局(如果子呈现器是 dirty 的,或者这是全局布局,或出于其他某些原因),这会计算子呈现器的高度。- 父呈现器根据子呈现器的累加高度以及边距和补白的高度来设置自身高度,此值也可供父呈现器的父呈现器使用。
- 将其 dirty 位设置为 false。
绘制
在绘制阶段,系统会遍历呈现树,并调用呈现器的“paint”方法,将呈现器的内容显示在屏幕上。绘制工作是使用用户界面基础组件完成的。
记录点 5 呈现引擎采用了单线程。几乎所有操作(除了网络操作)都是在单线程中进行的。
在 Firefox 和 Safari 中,该线程就是浏览器的主线程。而在 Chrome 浏览器中,该线程是标签进程的主线程。
网络操作可由多个并行线程执行。并行连接数是有限的(通常为 2 至 6 个,以 Firefox 3 为例是 6 个)。
浏览器渲染页面的五个阶段:
- 解析html文档,生成节点,构建dom树;
- 在阶段一中,如果遇到css(内嵌在html文档或者外链或者内联样式都一样),则会解析css文档,生成cssom
- 阶段一和阶段二都是可以并行的,等到dom和cssom准备好,会进行合并,生成render tree
- 布局处理
- 绘制
补充说明: 浏览器并不会等解析完完整的html文档后,才进行layout 和paint。浏览器已经对显示html文档进行了优化,会尽快将解析好的部分呈现给用户。也就是,上图所谓的一次渲染过程,在分块传输的时候,是可以多次进行的。直到接收到body, html 的闭合标签。
事件循环
记录点 6 浏览器的主线程是事件循环。
浏览器的主线程是事件循环。它是一个无限循环,永远处于接受处理状态,并等待事件(如布局和绘制事件)发生,并进行处理。
这是 Firefox 中关于主事件循环的代码:
while (!mExiting)
NS_ProcessNextEvent(thread);
CSS 框模型
定位方案
有三种定位方案:
- 普通:根据对象在文档中的位置进行定位,也就是说对象在呈现树中的位置和它在 DOM 树中的位置相似,并根据其框类型和尺寸进行布局。
- 浮动:对象先按照普通流进行布局,然后尽可能地向左或向右移动。
- 绝对:对象在呈现树中的位置和它在 DOM 树中的位置不同。
定位方案是由“position”属性和“float”属性设置的。
- 如果值是 static 和 relative,就是普通流
- 如果值是 absolute 和 fixed,就是绝对定位
static 定位无需定义位置,而是使用默认定位。对于其他方案,网页作者需要指定位置:top、bottom、left、right。
How Browsers Work: Behind the scenes of modern web browsers
Slides: how browsers work
Webpage rendering
Repaint and reflow
w3.org
https://trac.webkit.org/wiki/LayoutUnit
至此,结束。