Skip to content
目录

浏览器从输入URL后经过了什么?

地址栏输入URL时,你的输入将由浏览器进程的UI线程处理

大体流程

1.处理输入
UI线程判断这是一次搜索查询还是一个URL地址,决定将请求发送到搜素引擎或是请求对应网站

2.开始导航
按下Enter键时,UI线程启用网络调取去获取站点内容

3.建立连接
网络线程会通过适当的协议,为请求建立连接 具体包括DNS查找、建立TCP连接、建立TLS连接

4.读取响应
连接建立完成后,将发送一个http请求以获取网站数据 在服务器接收请求并处理后,会返回响应数据 一旦浏览器开始收到响应主体(payload),网络线程会在必要时查看数据流的前几个字节。响应报文的Content-Type字段会声明数据的类型,但它有可能会丢失或者错误,所以有了MIME类型嗅探来解决这个问题 如果响应的是一个HTML文件,那么下一步就会把数据传给渲染进程,但是如果是一个压缩文件或是其他文件,那么意味着它是一个下载请求,因此需要将数据传递给下载管理器 此时也会进行SafeBrowsing检查。如果域名和响应数据似乎匹配到一个已知的恶意网站,网络线程会显示一个警告页面。除此之外还会发生Cross Origin Read Blocking [CORB]检查,以确保敏感的跨域数据不被传给渲染进程

5.查找渲染进程
一旦所有的检查执行完毕并且网络线程确定浏览器会导航到请求的站点,网络线程会告诉UI线程所有的数据准备完毕。UI线程会寻找渲染进程去开始渲染web页面 这里可以应用一个优化措施,当UI线程发送一个URL请求给网络线程时,它以及知道他们会导航到哪个站点。在网络请求的同时,UI线程并行的尝试主动寻找或开启一个渲染进程。这样如果一切按预期进行,在网络线程接收到数据使渲染进程就一斤待命。如果导航跨域重定向,这个待命进程也许不会被用到,这种情况下也许会用到另一个进程

6.提交导航
现在数据和渲染进程已经就绪,浏览器进程发送一个IPC(进程间通讯)到渲染进程去提交导航。一旦浏览器进程收到渲染进程已经提交的确认消息,导航完毕并且文档加载解析开始

7.渲染界面
浏览器解析HTML,渲染出HTML界面

8.断开TCP连接
界面加载完成,断开TCP连接

(3)建立连接详细解析

(7)渲染界面详细解析

7.1解析
当渲染进程收到导航的提交信息并开始接收HTML数据时,主线程开始解析文本字符串(HTML)并将其转换为文档对象模型(DOM)

构建DOM树

7.2子资源加载
图像、CSS和JavasScript等外部资源,这些文件需要从网络或缓存加载.解析构建DOM时,主线程会按处理顺序逐个请求他们,但为了加快速度,预加载扫描器会同时运行。如果文档中由img link之类的内容,预加载扫描器会查看由HTML解析器生成的标记,并在浏览器进程中向网络线程发送请求

7.3JavaScript阻塞解析
当HTML解析器遇到script标签时,会暂停解析HTML文档解析,会开始加载、解析并执行JavaScript代码

你可以为link标签添加rel="preload"属性或为script标签添加async或defer属性,提示浏览器如何加载资源

7.4样式计算
CSS文件加载完毕后,主线程解析CSS并确定每个DOM节点计算后的样式,即使你不提供任何CSS,每个DOM节点都具有计算样式

构建CSSOM树

7.5构建渲染树
浏览器在DOM树和CSSOM树构建完毕后,会将他们合并成渲染树

7.6布局
布局是计算元素几何形状的过程。主线程遍历DOM,计算样式并创建布局树,布局树可能与DOM树结构类似,但它仅包含页面上可见内容相关的信息

7.7绘制
主线程遍历布局树创建绘制记录,绘制记录是绘图过程的记录(比如包含了绘制的先后关系等)

更换渲染管道的成本很高,渲染管道中最重要的事情是:每个步骤中,前一个操作的结果用于后一个操作创建新数据。例如布局树中某些内容发生改变,需要为文档的受影响部分重新生成绘制指令

7.8分层


为了分清哪些元素位于哪些图层,主线程遍历布局树创建图层树(DevTools性能面板中称为"Update Layer Tree")。如果页面的某些部分应该是单独图层(比如划入式侧面菜单)但没拆分出来,你可以使用CSS中的will-change属性来提示浏览器

7.9合成
浏览器知道文档的结构、每个元素的样式、页面的几何形状和绘制顺序,把这些信号转换为屏幕上的像素,我们称为光栅化
合成将页面的各个部分分层,分别光栅化,并在称为合成线程的单独线程中合成为页面。如果发生滚动,由于图层已经光栅化,因此它只需要合成一个新帧

7.10主线程的光栅化和合成
一旦创建了图层树并确定了绘制顺序,主线程就会将该信息提交给合成线程。接着,合成线程会光栅化每个图层。一个图层可能会跟整个页面一样大,因此合成线程将他们分块后发送到光栅线程。光栅线程光栅化每个小块后会将他们存储在显存中
合成线程会给不同的光栅线程设置优先级,以便视窗附近的画面可以先被光栅化,一旦块被光栅化,合成线程会收集这些块的信息(称为绘制四边形)创建合成帧。 接着合成帧通过IPC(进程间通讯)提交给浏览器进程,这些合成帧被发送到GPU然后再屏幕上显示

(8)断开连接详细解析

Released under the MIT License.