1、构建请求行
GET / HTTP/1.1
2、查找强缓存
命中 -> 使用缓存,返回200
3、DNS解析
- 检查浏览器自身缓存是否有该域名对应的IP
- 检查本地host文件网址映射
- 检查TCP/IP参数中设置的首选服务器(本地DNS服务器LDNS),是否在本地配置区域资源中
- 到根域名服务器进行解析,根域名服务器返回所查域的主域名服务器gTLD地址(.com,.cn,……)
- 到主域名服务器进行解析,主域名服务器返回网站注册的域名服务器地址(Name Server)
- 网站服务器找到目标ip返回给本地DNS服务器
- 本地DNS服务器缓存该域名和地址并返回结果给浏览器
4、建立TCP连接
三次握手:为了确认服务端和客户端的接收能力和发送能力是否正常
TCP头部信息:
- 16位源端口号
- 16位目的端口号
- 32位序号
- 32位确认号(对方报文序号+1)
- 4位头部长度
- 6位标准位(URG、ACK、PSH、RST、SYN、FIN)
- 16位窗口大小
- 16位校验和
- 16位紧急指针
http://cdn.yuanrengu.com/img/%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B.jpg
具体参考三次握手、
4.5、SSL/TLS握手(针对HTTPS)
client -->> server:client_hello,版本号、随机数(用于密钥生成)、支持的加密算法
client <<-- server:server_hello,版本号、随机数(用于密钥生成)、选择一个客户端支持的加密算法
client <<-- server:sever_certificate,服务端配置对应的证书,用于身份验证和密钥交换
client <<-- server:sever_hello_done,表示server_hello发送结束
client:客户端验证证书的合法性
client -->> server:client_key_exchange,客户端计算产生随机数Pre-master,用证书公钥加密发送给服务器(此时客户端已拿到所有密钥信息)
client -->> server:change_cipher_spec,客户端通知服务器后续的通信都采用协商的通信密钥和加密算法进行加密通信
client -->> server:encrypted_handshake_message,之前的通信参数的hash值加密后发送给服务端用于握手验证
client <<-- server:change_cipher_spec,解密数据并验证,通过后,发送同样加密的数据encrypted_handshake_message
但是也不是每次发送请求都要经历上述的所有过程,可以通过一个Session Identifier(会话标识符),该Session ID是 TLS 握手中生成的 Session ID。服务端可以将 Session ID 协商后的信息存起来,浏览器也可以保存 Session ID,并在后续的 Client Hello 握手中带上它,如果服务端能找到与之匹配的信息,就可以完成一次快速握手。
5、发送HTTP请求
包括:
- 请求行:请求方法(GET,POST),请求URI,HTTP协议版本
- 请求头:HOST、Connection、Cookie、Expires、Cache-Control、If-Modified-Since、If-None-Match、User-Agent
- 请求体:例如POST提交的表单
6、接收服务器响应
包括:
- 响应行:HTTP协议版本,状态码,状态描述
- 响应头:Connection、Set-Cookie、Cache-Control、Date、Etag、Last-Modified
- 响应体:数据
如果Connection为keep-alive,则TCP保持连接,不进行挥手
Content-Type值为text/html时进行浏览器渲染
7、构建DOM树
1、生成标记
2、通过堆栈入栈出栈建树:
<html> -->> HTMLHtmlElement
<head> -->> HTMLHeadElement
<body> -->> HTMLBodyElement
并有一定的容错策略
8、计算样式
- 格式化样式:将css文本转换为结构化的对象 —— document.styleSheets
- 标准化样式:while -> #000、bold -> 600
- 计算每个节点的样式:继承(使用父节点的样式) + 层叠(BFS,GFS……)
计算后的样式会时刻挂载到window.getComputedStyle上
9、生成布局树(layout tree)
1、遍历DOM树的节点,并将其添加到布局树中
2、计算布局树中的节点坐标位置
注意:head标签会默认display: none,chrome会使用Skia渲染
10、渲染
1、建立图层树
一般来说,当前节点图层会默认属于父节点的图层
2、生成绘制列表
将图层绘制拆分成一个个绘制指令,比如先画背景、再描绘边框......然后将这些指令按顺序组合成一个待绘制列表,相当于给后面的绘制操作做了一波计划
3、生成图块并栅格化
将图层分块、绘制视口附近的图块、首屏展示只展示低分辨率的图片、图块绘制后替换掉图片、生成位图数据
4、显示内容
浏览器绘制进程 - -》 显卡 --》显示器刷新展示图片
11、重排和重绘
触发重排:楼上的过程会重来一遍
- DOM大小改变:border、width、height、padding、margin
- DOM节点数量改变或者位置移动
- 读取offset、scroll、client属性族
- 调用getComputedStyle、getClientRects
触发重绘:
DOM自身几何属性不变,不需要更新位置信息,从而省掉了布局的过程
参考: https://www.html5rocks.com/zh/tutorials/internals/howbrowserswork/#1_1