什么是浏览器
Web浏览器(英语:Web Browser,常简称为浏览器)是一种用于检索并展示万维网信息资源的应用程序。这些信息资源可为网页、图片、影音或其他内容,它们由统一资源标志符标识。信息资源中的超链接可使用户方便地浏览相关信息。
网页浏览器虽然主要用于使用万维网,但也可用于获取专用网络中网页服务器之信息或文件系统内之文件。
主流网页浏览器有Mozilla Firefox、Internet Explorer、Microsoft Edge、Google Chrome、Opera及Safari。
那么这些浏览器都是怎么来的?在介绍浏览器是怎样运作前,我们先了解一下浏览器发展的历史。
浏览器的发展史
-
1991 年 Berners Lee 建立了第一代网络浏览器 WorldWideWeb ,只支持显示文本图片。
-
1993 年 伊利诺大学的 NCSA 组织发布了Mosaic 网页浏览器,这是互联网历史上第一个获普遍使用和能够显示图片的网页浏览器。
-
1994 年 Netscape Navigator(网景浏览器) 发布,由曾经参与 Mosaic 研发的人共同创建,虽然只能显示静态的 html,没有 js 和 css,但依然在全球大放异彩,占领了绝大多数市场份额;同年出现了 Opera 浏览器。
-
1995 年 微软发布 IE 1.0 和 IE 2.0,第一次浏览器大战拉开序幕。
-
1996 年 微软在 Windows 操作系统中集成了 IE 3.0,将其作为免费软件提供给 Windows 用户使用,此时网景浏览器的市场份额占有已接近 86%。
-
1998 年网景公司在成立了 Mozilla 基金会,在该基金会的推动下,开发了著名的开源项目(2004年 Firefox)。
-
1999 年 随着 Windows 操作系统的普及,网景浏览器的市场份额逐渐被 IE 浏览器 所占有,到 1999 年 IE 浏览器的市场占有率已达到 99%。
-
2003 年苹果公司发布 Safari 浏览器,该浏览器内置在所有苹果操作系统中。
-
2004 年 网景公司发布 Firefox 浏览器 1.0 版本,宣告着第二次浏览器大战正式打响。
-
2005 年苹果公司开源了 Safari 浏览器的内核 Webkit
-
2008 年谷歌公司以 Webkit 为内核创建了项目 Chromium,在该项目基础上,谷歌发布了自己的浏览器 Chrome
浏览器的结构
浏览器的结构主要由三部分组成:用户界面、浏览器引擎、渲染迎请;其中渲染引擎是浏览器的核心,也成为 内核。
浏览器是个多进程结构
- 浏览器进程 :控制除标签页外的用户界面,包括地址,书签,后退,前进按钮等,以及负责与浏览器其他进程负责协调工作
- 缓存进程
- 网络进程:发起网络请求
- 渲染器进程 :将html、js、css、image等资源渲染成 Web 页面 ,可能会为每个页面都开启一个渲染器进程(与选择的进程模型相关)
- GPU 进程 :负责整个浏览器界面的渲染
- 插件进程 :控制所有内置插件
渲染进程的过程
下面说下渲染进程的过程
浏览器通过网络请求后获取 html 数据,通过 tcp 传给渲染器进程
- Dom:主线程将 Html 解析构造 Dom Tree
- Style:样式计算
- LayoutTree:根据 DomTree 和样式生成 LayoutTree
- Paint(绘制): 通过遍历 LayoutTree 生成绘制顺序表
- Laryer(布局 ): 然后根据主进程将 LayoutTree 和绘制信息表传给合成器线程
- 合成器线程 :将得到的信息分图层分成更小的图块
- 栅格线程:将更小的图块进行栅格化 raster,返还给合成器线程 Draw Quads 图块信息,存储在 GPU 中
- Frame(合成器帧):合成器将栅格线程返回的图块合成帧交给浏览器进程
- 浏览器进程:收到一帧的图像后传给 GPU 进行渲染
重排
当改变DOM的属性时,会重新进行样式计算,会重新布局和绘制。
重绘
当改变颜色时,只会发生样式计算和绘制(Layer)
重排和重绘导致的问题
由于重排和重绘会占用主线程的时间,而 JS 也同样位于主线程,因此会发生抢占执行时间的问题。当两帧运行之间的JS 没有及时归还主线程时就会发生卡顿。
- RequestAnimationFrame() :会将主线程的任务分散到每一帧的间隔,从而不影响动画的流程
- React Fiber :利用浏览器的空闲时间做优化
- Transform :会直接运行合成器线程,所以不会感染主线程的渲染
在移动端使用3d转换可以优化性能(如果设备有3d加速引擎 GPU 可以提高性能 , 2d转换是无法调用GPU,2G是靠的CPU)
总结
总结一下浏览器渲染过程:
- 网络线程获取 Html 数据后,通过 IPC 将数据传给渲染器进程的主线程,主线程将 Html 解析构建 Dom 树,然后进行样式计算。根据 Dom 树和生成好的样式生成 LayoutTree ,通过遍历 LayoutTree 生成绘制顺序表,接着遍历 LayoutTree 生成 LayerTree
- 主线程将 LayerTree 和绘制顺序信息一起传给合成器线程,合成器线程按照规则进行分图层,并把图层分为更小的图块 Tiles 传给栅格线程进行栅格化。
- 栅格化完成后合成器线程会收到栅格化线程传过来的 Draw Quads 图块信息,根据这些信息,合成器线上合成了一个合成器帧。然后将该合成器帧通过 IPC 传给浏览器进程,浏览器进程再传到 GPU 进行渲染,最后就展示在屏幕上了。