流程图

一些准备工作
浏览器先构建请求行: GET/index.html HTTP1.1
查找强缓存:查看浏览器缓存中是否有资源,有则返回该资源的副本,并直接结束请求了
1.DNS域名解析
在输入域名之后,客户端首先查找本地hosts文件(用户很少去编辑修改hosts文件)
检查在该hosts文件中是否有相应的域名、IP对应关系。
如果有,则直接发起请求。如果没有,再查找DNS服务器得到对应IP地址
2.建立TCP连接
TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议
拿到IP之后,客户端就可以和服务端建立TCP连接了。 这时候就要进行三次握手来建立TCP链接
- 客户端发送 SYN标志的数据包 给服务端
- 服务端发送 SYN/ACK标志的数据包 给客户端
- 客户端发送 ACK标志的数据包 给服务端
三次握手本质上是确定客户端和服务端的接受和发送能力都正常
- Chrome在同一个域名下要求同时最多只能有6个TCP连接,超过6个的话。其余就得等待
3.发送HTTP请求
建立TCP连接之后,就可以向服务器发送HTTP请求了 HTTP请求包含的三个部分(请求行,请求头,请求体)
- 请求行 GET/index.html HTTP1.1
- 请求头(Request Headers)
- 请求体(Request Body) 只有在POST方法下存在 常见场景是表单提交
4.服务器处理请求
在收到客户端发送的HTTP请求之后,服务器开始处理请求
如(Apache、Nginx、IIS等服务器)解析用户请求 并进行一系列操作 如下图

5.返回响应结果
处理完请求后,服务器把数据传给浏览器。 响应结果也有三个部分(响应行,响应头,响应体)
- 响应行 HTTP/1.1 200 OK 由HTTP协议版本、状态码和状态描述组成。
- 响应头(Response Headers)
- 响应体 一般是HTML文件
6.关闭TCP连接
返回响应结果之后,是否就要关闭TCP连接了呢? 答案是不一定
Connection:Keep-Alive
如果浏览器或者服务器头信息有上面的字段的话,TCP连接会仍然保持
保持TCP连接可以节省下次请求需要建立TCP连接的时间,提升资源加载进度。
当要关闭TCP连接的时候,这时候就需要四次挥手
- 客户端发送FIN报文给服务端 (兄弟,我这边已经没有数据要传了,关闭吧关闭吧)
- 服务端发送ACK报文给客户端 (收到了收到了! 我看看我还有没有数据要传)
- 服务端发送FIN报文给客户端 (兄弟,我这边也没有数据要传了,关闭吧关闭吧)
- 客户端发送ACK报文给服务端 (收到了收到了!)
7.浏览器解析HTML(获得DOM树和DOM树中元素的样式)

7.1构建DOM树
DOM树本质上是一个以document为根节点的多叉树
浏览器将HTML字符串转换为一种有意义并且方便操作的数据结构=> DOM树
- 常规的编程语言都是上下文无关文法,而HTML却是非上下文无关的特性
- 所以HTML的解析算法分为两个阶段: 1.标记化 2.建树
标记化算法:将输入的HTML文本输出为HTML标记
建树算法: 将HTML标记创建对应的DOM对象
7.2样式计算
- (1)格式化 样式表
将CSS文本转化为一个结构化对象 styleSheets(在控制台输入document.styleSheets可以查看) - (2)标准化 样式属性
CSS文本中有很多属性值如2em、blue、bold,这种类型数值不容易被渲染引擎理解。
所以需要将所有值转换为渲染引擎容易理解的、标准化的计算值。() - (3)计算 DOM树中每个节点的具体样式
主要是涉及到CSS的两个规则:1.继承2.层叠
继承:父元素设置一些属性, 子元素也可以使用,比如颜色,字体,字体大小等属性都可以被继承。
层叠:层叠是CSS的一个基本特征,它是一个定义了如何合并来自多个源的属性值的算法。它在CSS处于核心地位,CSS的全称“层叠样式表”正是强调了这一点。 最终输出的内容是每个DOM节点的样式,并被保存在ComputedStyle的结构内(window.getComputedStyle)
8.浏览器布局渲染(计算DOM树中可见元素的几何位置)

8.1构建布局树
- 将DOM树中可见元素添加到一棵只包含可见元素的布局树中(Layout Tree)
8.2布局计算
- 布局树 => 布局运算 => 计算好节点坐标位置的布局树
8.3分层
- 计算好节点坐标位置的布局树 => 显式合成及隐式合成 => 生成图层树(Layer Tree)
8.4图层绘制
- 将图层树中的每个图层进行绘制,得到一个绘制列表。列表里是一组记录绘制步骤的指令,每个指令都是一个简单的绘制操作(绘制一个矩形或者画一条线)。
通过Chrome 开发者工具more tools 选择Layers面板可以看到
8.5栅格化(通过GPU生成位图)
栅格化的过程主要使用GPU来加速生成,完成后发送给合成线程
8.6合成和显示
栅格化操作完成之后,合成线程生成一个绘制命令,即"DrawQuad",发送给浏览器进程
浏览器进程的viz组件接受到命令之后,将页面内容绘制到内存,再将这部分内存发送给显卡
当内存不够时,浏览器生成图像的速度变慢,图像发送给显卡就不及时。而显示器的刷新频率是固定的,一般是60HZ(60帧),所以会出现卡顿的情况
相关知识
重绘与回流
TCP协议的三次握手四次挥手
性能优化