浏览器是如何加载网页的

本文中提到的浏览器如无特殊说明皆为chrome浏览器。

浏览器

在访问网页之前,首先要打开浏览器。这时候浏览器会打开至少四个进程,分别如下:

浏览器架构图

浏览器主进程

负责浏览器主UI、与用户的交互、持久化的数据管理(cookie、localStorage等)、管理其他子进程等。

渲染进程

核心进程,页面的HTML、CSS、JavaScript会在渲染进程中处理。

GPU进程

页面使用GPU进行绘制。一开始只使用GPU来绘制CSS3等动画,后来则将渲染工作全部交给GPU来处理了。

网络进程

负责网络请求的处理。

插进进程

如果有安装插件,那么插件会运行在一个单独的进程里,与其他进程隔离开,避免插件崩溃影响其他进程。像是开发Vue项目必备Vue Dev Tool,在开发过程中经常崩溃,如果没有进程隔离,那么开发体验会进一步拉胯。

浏览器准备好了上述进程,下面该打开一个具体的网页了。

解析网页

请求网页

不论是在地址栏中输入网址,还是从google中搜索打开,浏览器都会发送一个HTTP请求到服务器,请求指定的网页内容。只要这个HTTP请求的response header中Content-Type = text/html, 浏览器就会以HTML解析器的方式来解析响应体中的内容。

解析DOM树

body中的html标签会被解析成DOM树(Document Object Model),并将这些DOM树放在内存中,这样我们就可以通过JS对它进行操作。比如直接修改他的背景色:document.getElementById('app').style.backgroundColor = 'white'

解析CSS OM树

style标签与link标签外链的CSS会被解析成CSS StyleSheet(可以通过document.styleSheets查看),然后解析成CSSOM(CSS Object Model)树,与DOM树进行匹配。

合成布局树

在合成布局树之前,会先筛选一下,排除不可见的元素,比如 display:none。 然后将DOM树与CSSOM树进行匹配,开始逐个计算元素的布局。

绘制

划分图层

具有动画效果、Z轴排序等层叠上下文属性或需要高性能的元素会被划分到独立的图层,比如canvas。个人理解这样一是可以方便实现层叠效果,而是有利于提升性能,比如动画期间仅修改独立的某个图层的内容。

生成指令

将图层绘制拆分成小的指令。

划分图块

将图层划分成256 / 512大小的方形图块,这样可以优先绘制可视窗口(viewport)的图块内容,减少初次绘制压力。

栅格化

将图块转化为栅格图,也叫位图,就是像素点图。

合成与现实

将栅格化好的图块绘制到内存中,最终显示到屏幕上。

渲染流程概览