浏览器原理
约 1697 字大约 6 分钟
2025-06-21
1.浏览器的现有商家
现在主流的浏览器主要由 Chrome、Edge/IE、Firefox、Safari、Opera 这五款浏览器,其中笔者对 Chrome 使用的时间较久。
2.浏览器的主要功能
浏览器的主要功能是从服务器请求您选择的 Web 资源,并将其显示在浏览器窗口中。资源通常是 HTML 文档,但也可能是 PDF、图片或其他类型的内容。资源的位置由用户使用 URI(统一资源标识符)指定。
HTML 和 CSS 规范中指定了浏览器解读和显示 HTML 文件的方式。这些规范由 W3C, 万维网联盟 组织维护,该组织是网络标准组织。多年来,浏览器仅遵循了部分规范,并开发了自己的扩展程序。这给网站作者带来了严重的兼容性问题。目前,大多数浏览器或多或少都符合规范。
浏览器界面有很多共同之处。常见的界面元素包括:
- 用于插入
URI的地址栏 - “返回”和“前进”按钮
- 书签选项
- 用于刷新或停止加载当前文档的“刷新”和“停止”按钮
- 用于前往首页的主屏幕按钮
奇怪的是,浏览器的界面并未在任何正式规范中指定,而是来自多年经验形成的良好做法,以及浏览器相互模仿的结果。HTML5 规范未定义浏览器必须具备的界面元素,但列出了一些常见元素。其中包括地址栏、状态栏和工具栏。当然,有些功能是特定浏览器独有的。
3.浏览器的工作流程
浏览器会解析三个文件。
HTML/SVG/XHTML文件,事实上,Webkit有三个Cpp的类对应这三类文档,解析这三种文件会产生一个DOM TreeCSS文件,解析CSS会产生CSS Rule Tree,实际上建立CSS Rule Tree是需要比照着DOM Tree来的JS文件,主要是通过DOM API和CSSOM API来操作DOM Tree和CSS Rule Tree
解析完成后,浏览器引擎会通过
DOM Tree和CSS Rule Tree来构造渲染树Render Tree。Render Tree并不等同于DOM Tree,因为一些像<head>或display:none的东西就没必要放在Render Tree中了,反正都是写不用显示出来的东西CSS Rule Tree主要是为了完成匹配并把CSS Rule附加上Render Tree上的每个Element然后计算每个
Element的位置,这又叫layout布局过程和reflow回流过程
最后通过调用操作系统
Native GUI的API绘制。
重要
补充:WebKit 是一个跨平台的浏览器引擎库,早期被大多数浏览器所使用,虽然 WebKit 仍然是 Safari 的渲染引擎,但 Google 在 2013 年从 WebKit 分叉出了 Blink,并用于 Chrome、Edge 中(也就是 Chromium 内核)等浏览器。因此,现在的 Chrome 和 Edge 已经不再使用 WebKit,而是基于 Blink。
重要
补充:布局过程和回流过程的区别很大。
- 布局过程:计算元素的尺寸和位置,例如:宽度、高度、边距、内边距、边框等。确定每个元素在页面上的具体位置,即确定它们的坐标。布局过程是基于
Render Tree计算所有可见元素的位置和大小。在这一步骤中,浏览器计算元素的坐标(左上角的位置),并为其分配空间。布局过程发生在页面渲染时,通常是在回流过程中进行的。 - 回流过程:回流是布局过程的再计算,在页面中的元素几何信息发生变化时触发。它会导致重新计算布局,更新元素的位置、尺寸等信息。触发回流的操作包括:a.改变元素的大小(例如宽高、内外边距) b.
DOM结构的变化(比如添加、删除元素) c.窗口大小变化 d.改变元素的位置属性(例如position、top、left) e.获取布局信息,如offsetWidth、offsetHeight等。但性能开销较大,尤其是在大规模DOM操作时,回流会影响到页面的渲染效率。
注意
警告:CSS 匹配 HTML 元素是一个相当复杂和有性能问题的事情。所以,您会在 N 多地方看到很多人都告诉您,DOM 树要小,CSS 尽量用 id 和 class,千万不要过度层叠下去。
注意
警告:多次的回流是浏览器性能的瓶颈之一,在某些场景下,会导致浏览器卡死,一般来说,浏览器会把样式修改这样的操作积攒一批,然后做一次 reflow,这又叫异步 reflow 或增量异步 reflow。但是有些操作无法避免,例如修改窗口的大小。
因此在现代浏览器编写中,通常都会做以下的优化:
- 不一条一条地修改
DOM的样式。与其这样,还不如预先定义好CSS的class,然后修改DOM的className(这在一些框架中也叫动态绑定)。 - 把
DOM离线后修改。比如使用documentFragment对象在内存里操作DOM,先把DOM给display:none(有一次reflow),然后想怎么改就怎么改。比如修改100次,然后再把他显示出来。亦或者clone一个DOM结点到内存里,然后想怎么改就怎么改,改完后,和在线的那个的交换一下。 - 不要把
DOM结点的属性值放在一个循环里当成循环里的变量,不然这会导致大量地读写这个结点的属性。为了避免频繁读写DOM属性,我们可以将需要修改的属性值先缓存到一个变量中,进行批量修改后再应用到DOM上。 - 尽可能的修改层级比较低的
DOM。当然,改变层级比较底的DOM有有可能会造成大面积的reflow,但是也可能影响范围很小。 - 为动画的
HTML元件使用fixed或absoult的position,那么修改他们的CSS是不会reflow的。因为这类元素的定位行为与普通流式布局的元素不同,它们的布局过程在文档流中是独立的,不会影响其他元素的排版和布局。 - 千万不要使用
table布局。因为可能很小的一个小改动会造成整个table的重新布局,性能较差,另外丧失了语义性。
存在一些工具可以检测回流的情况以优化性能,例如 Google 的 Speed Tracer。
4.浏览器的渲染引擎
更新日志
版权所有
版权归属:898738804@qq.com