从页面输入URL到页面展示过程中发生了什么
这个问题在面试中出现的频率实在是不要太高,虽然看了很多关于此的文章,但心中一直没有给自己过一个说的过去的答案。今天在看李兵老师的浏览器工作原理与实践时发现了很多的细节,准备用自己的话总结一下,但是我又怕我说错了所以也会引用一些老师的原话,希望尽量可读性高一点-.-
-
大体介绍一下chrome浏览器多进程架构chromium。主要有五个进程
- 浏览器主进程:负责处理用户交互,管理子进程以及存储文件
- 网络进程:负责发送请求,下载资源等
- 渲染进程:负责解析html、js、css文件以及图片资源,将其解析为可以展示的界面
- GPU进程:加速渲染
- 插件进程:负责执行插件
-
这个过程需要浏览器各个进程之间的协作,大体过程如下:
- 浏览器主进程接收到用户输入URL后将其发送给网络进程
- 网络进程发送http/https请求给服务端,解析响应头数据,将数据转发给浏览器主进程
- 浏览器主进程通知渲染进程(发送提交导航消息给渲染进程)
- 渲染进程收到提交导航的消息开始准备接收HTML数据,跟网络进程进行通信
- 渲染进程向浏览器主进程确认提交,告诉主线程渲染进程已经准备好接收数据了
- 浏览器进程接收到渲染进程“提交文档”的消息之后,便开始移除之前旧的文档,然后更新浏览器进程中的页面状态
用户输入
- 用户在地址栏输入内容后,地址栏会判断是搜索内容还是url地址
- 如果输入的是关键词搜索内容,地址栏使用默认的搜索引擎拼接成带关键字的url
- 若是url地址,地址栏会为其加上协议http/https
- 点击确认后,浏览器更新页面前会在当前页面执行beforeunload事件,若当前页面有表单未提交的情况可在此方法中阻断接下来的流程,继续提交表单
URL网络请求
此时浏览器主进程向网络进程发送URL,之后流程由网络进程发送请求
这里的操作感觉谁都知道,就不展开说了0.0,如果真的需要的话 也可以补上
- 查找缓存
- DNS解析,获取IP地址
- TSL握手
- TCP握手
- 发送http/https请求
- 解析响应头,通知主进程
启动一个渲染进程
一般一个标签对应一个渲染进程,如果两个地址同属一个站点(规则为,跟域名baidu.com与协议相同)则公用同一个渲染进程;
提交文档-确认提交
浏览器主进程发送提交文档的消息给渲染进程,渲染进程收到后与网络进程进行链接;准备好后向主进程发送确认提交的消息表示已经可收,此时浏览器开始更新前进后退按钮、地址栏url、安全状态以及web页面;之后渲染进程开始渲染流程
渲染
- 构建DOM树,输出DOM树
- 把HTML文件解析成浏览器能够理解的DOM树结构
- 计算样式,输出ComputedStyle
- 将css解析为浏览器能够理解的styleSheet样式表
- 将属性值标准化,比如用到em,rem的单位都转化为px,颜色转化为rgb等
- 将每个dom节点的样式映射,形成ComputedStyle,根据继承和层叠的规则
- 布局,生成布局树LayoutTree
- 将dom树中不显示的节点去掉,比如display为none的节点生成布局树LayoutTree
- 计算布局树中每个节点的几何位置,最后写入到布局树中
- 分层,生成图层树LayerTree
- 根据分层规则将布局树分层形成LayerTree
- 拥有层叠上下文属性的节点生成新图层,例如position,float,Z-index等属性
- 有截取的节点生成新图层,overflow属性
- 根据分层规则将布局树分层形成LayerTree
- 图层绘制,生成绘制列表
- 渲染进程创建好图层树后开始准备绘制,首先要根据图层生成绘制列表(保存绘制图层树的步骤,比如先绘制方块再绘制方块上面的圆),之后将绘制列表交给合成线程,下面任务由合成线程完成
- 栅格化,生成位图
- 由于视口大小有限,合成线程会将图层分为图块(256256 / 512512),将视口附近的图块先交给珊格化线程池进行生成位图的操作
- 珊格化线程池一般会借助GPU进程进行加速生成位图,图层操作都完成时会通知浏览器主进程进行显示操作
- 合成和显示,生成页面
- 浏览器主进程将生成的位图存于内存中,最终配合显卡展示为页面
最后
如果有写错的地方希望大家帮我在评论区指出,我会及时修改呦。