1.过程概述
- dns解析域名获得IP(在这个之前还有浏览器进程检查url,组装协议,构成完整的url的过程)
- 浏览器根据IP与服务器建立TCP连接
- 浏览器发起HTTP请求
- 服务器处理请求并返回HTTP报文
- 浏览器解析渲染页面
- 浏览器与服务器断开连接
2.dns解析域名获得IP
域名解析的过程是逐级查询的
查看dns解析记录 dig math.stackexchange.com
dns解析域名的过程如下:
- 浏览器缓存
- 操作系统缓存
- host文件中查找
- 由器缓存
- ISP DNS缓存 互联网服务提供商(阿里 百度之类)
- 顶级DNS服务器/根DNS服务器

3.TCP连接 Browser Service
- 三次握手与四次挥手

- 三次握手 确认发送方与接收方的 发送接收能力
- Browser ——> Service Browser发送SYN包SYN=1,初始序号seq=x 进入SYN-SENT状态 等待Service确认
- Service ——> Browser Service发送确认报文段中SYN=1,ACK=1,确认号ack=x+1,初始序号seq=y 进入SYN-RECEIVED状态
- Browser ——> Service Browser发送确认报文段ACK=1,确认号ack=y+1,序号seq=x+1 进入ESTABLISHED状态 等待Service收到包之后 状态切换为ESTABLISHED
- 四次挥手
- Browser ——> Service Browser发出连接释放报文段(FIN=1,序号seq=u)停止再发送数据 主动关闭TCP连接,进入FIN_WAIT1(终止等待1)状态,等待服务端的确认
B:我要走了- Service ——> Browser 服务端收到 FIN 之后 Service发出确认报文段(ACK=1,确认号ack=u+1,序号seq=v)服务端进入CLOSE_WAIT(关闭等待)状态 客户端收到服务端的确认后,进入FIN_WAIT2(终止等待2)状态
S:我知道了- Service ——> Browser Service发出连接释放报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),服务端进入LAST_ACK(最后确认)状态
S:我也要走了- Browser ——> Service Browser发出确认报文段(ACK=1,seq=u+1,ack=w+1),客户端进入TIME_WAIT(时间等待)状态此时TCP未释放掉,服务端进入LAST_ACK,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。
B:知道了,再见
3.HTTP请求与响应
http(hyper text transfer protocol) 超文本传输协议,即定的规则,简单介绍HTTP的的请求响应格式,其中的各个字段意义移步http MDN。
- 请求
> 请求HTTP的格式
请求类型 请求URL 协议版本 扩展内容
请求头内容
Accept、Accept-Encoding、Accept-Chearset、Cookie、Host、user-agent...
空行
请求主体
- 响应
> 响应HTTP的格式
协议版本 响应状态码 描述 扩展内容
响应头内容
Content-type、Content-Encoding、Etag、Last-Modified、Pragma、Expires、Cache-Control、Date...
空行
响应主体
2.二次请求时,判断是否是有缓存可使用 - 缓存相关文章移步GitHub
4.浏览器解析渲染页面 webkit && gecko
- 处理HTML生成DOM tree
- 将http请求返回的原始字节转为字符 bytes => Characters(
<html>...</html>)- 将字符通过词法分析(XML)转为Tokens Characters(
<html>...</html>) => Tokens Token中会标识出当前Token是“开始标签”或是“结束标签”亦或是“文本”等信息- Token转化为节点对象(第2,3步骤同时进行) Token => Node DOM Token转化完毕 生成DOM tree

注意:带有结束标签标识的Token不会创建节点对象,上图表示构建DOM的具体步骤。首先生成出htmlToken,并消耗Token创建出html节点对象。然后生成headToken并消耗Token创建出head节点对象,并将它关联到html节点对象的子节点中。随后生成titleToken并消耗Token创建出title节点对象并将它关联到head节点对象的子节点中。最后生成bodyToken并消耗Token创建body节点对象并将它关联到html的子节点中。
- 处理CSS标记生成 styleSheets(CSSOM)
- 将http请求返回的原始字节转为字符 bytes => Characters(
body{...} p{...})- 将字符通过词法分析转为CSS分析树Token Characters(
body{...} p{...}) => Tokens- 将Tokens转为CSS规则树状图,并保持于每个元素和对应样式的映射关系 最终生成styleSheets
- 合并DOM tree 和 styleSheets 生成 render tree(webkit)或 frame tree(gecko)
生成渲染树的阶段DOM节点在styleSheets中根据元素,类,节点,ID选择器来提取与之对应的一条会多条CSSRule,提取完成,渲染树构建完成。 CSS样式有层叠的权重关系,后面的CSS可能会影响前面的CSS,必须等所有的CSS解析完成才能构建出准确的styleSheets,必须等整个styleSheets构建完成才能进行下一个阶段
注意:
1. 构建DOMtree 与 styleSheets 是同时进行的 但是当遇到没有defer、async的script标签,DOMTree的构建将被暂停,直至脚本执行完毕
2. JavaScript可以查询和修改DOMTree与styleSheets
3. 直至CSSOM构建完毕,JavaScript才会执行
4. 即:JS会阻塞DOMtree的构建 styleSheets会阻塞JS的执行 JS顺序排放应在CSS的后面 避免styleSheets的长时间单独构建
- 渲染引擎进行布局阶段(layout)
- 计算每个元素的几何坐标位置,并将这些信息保存在layoutTree中
- 为特定的节点生成专用的图层,并生成一棵对应的图层树layerTree
- 绘制阶段(paint)
- 浏览器渲染引擎实现每个图层的绘制,把一个图层的绘制拆分成按照顺序的待绘制指令列表 ++可以打开“开发者工具”的“Layers”标签,查看图层及图层的绘制列表++
- 绘制列表提交给合成线程,合成线程会将图层划分为图块,计算当前的视口,优先绘制当前视口附近的图块生成位图(过程成为栅格化,GPU进程中完成),所有图块栅格化完成,合成线程发送DrawQuad命令给浏览器进程,将页面内容绘制到内存,并显示到屏幕

参考文章
