基础版
- 浏览器根据请求的
RUL
交给DNS
域名解析,找到真实IP
, 向服务器发起请求; - 服务器交给后台处理完成后返回数据,浏览器接收文件(
THML、JS、CSS、
图像等); - 浏览器对加载到的资源(
HTML、JS、CSS
等) 进行语法解析,建立相应的内部数据结构(如HTML
的DOM
); - 载入解析到的资源文件,渲染页面,完成。
详细版
- 在浏览器地址栏输入RUL
- 浏览器直接查看缓存,如果请求资源在缓存中并且新鲜,跳转到转码步骤
- 如果资源未缓存,发起新请求。
- 过已经缓存,检验是否足够新鲜,足够新鲜直接提供给客户端,否则与服务器进行验证。
- 检验新鲜通常有两个 HTTP 头 进行控制
Expires
和Cache-Control
:- HTTP1.0 提供
Expires
, 值为一个绝对时间表示缓存新鲜日期。 - HTTP1.1 增加了
Cache-Control:max-age=
, 值为以每秒为单位的最大新鲜时间
- HTTP1.0 提供
- 浏览器解析URL获取协议,主机,端口, path
- 浏览器组装一个HTTP (GET) 请求报文
- 浏览器获取主机ip地址,过程如下:
- 浏览器缓存
- 本机缓存
- hosts 文件
- 路由器缓存
- ISP DNS 缓存
- DNS 递归查询(可能存在负载均衡导致每次IP不一样)
- 打开一个 socket 与目标 IP地址,端口简历TCP 连接,三次握手如下:
- 客户端发送一个 TCP 的
SYN=1, Seq=X
的包到服务器端口 - 服务器发回
SYN=1, ACK=X=1 ,Seq=Y
的响应包 - 客户端发送
ACK=Y+1, Seq=Z
- 客户端发送一个 TCP 的
- TCP 连接简历以后发送 HTTP 请求
- 服务器接受请求并解析,将请求转发到服务程序,如虚拟主机使用HTTP Host 头部判断请求的服务程序
- 服务器检查 HTTP 请求头是否包含缓存验证信息,如果验证缓存新鲜,返回 304 等对应状态码
- 处理程序读取完整请求并准备HTTP响应,可能需要查询数据库等操作
- 如武器将响应报文通过TCP 连接发送回浏览器
- 浏览器接受HTTP 响应,然后根据情况选择关闭TCP 连接或者保留重用,关闭TCP 连接的四次握手如下:
- 主动方发送
Fin=1, Ack=Z, Seq=X
报文 - 被动方发送
ACK=X+1, Seq=Z
报文 - 被动方发送
Fin=1, ACK=X, Seq=Y
报文 - 主动方发送
ACK=Y,Seq=X
报文
- 主动方发送
- 浏览器检查响应状态码: 是否为
1XX, 3XX, 4XX, 5XX
这些情况处理与不同2XX
- 如果资源科缓存,进行缓存
- 对响应进行 解码(例如gzip 压缩)
- 根据资源类型决定如何处理(假设资源未HTML文档)
- 解析HTML 文档,构建DOM 树,下载资源,构造CSSOM 树, 执行js 脚本,这些操作没有严格的先后顺序,一下分别解释
- 构建DOM 树:
- Tokenizing: 根据HTML 规范将字符流解析为标记
- Lexington: 此法分析将标记转换为对象并定义属性和规则
- DOM construction: 根据HTML 标记关系将对象组成DOM 树
- 解析过程中遇到图片、样式表、js文件、启动下载
- 构建CSSOM树:
- Tokenizing: 字符流转换为标记流
- Node: 根据标记创建节点
- CSSOM: 节点创建CSSOM 树
- 根据DOM 树和CSSOM 树构建渲染树:
- 从DOM 树的根节点遍历所有可见节点,不可见节点包括:①
script
,meta
这样本身不可见的标签。②被css 隐藏的节点,如:display: none
- 对每一个可见节点,找到恰当的
CSSOM
规则并应用。 - 发布可视节点的内容和计算样式
- 从DOM 树的根节点遍历所有可见节点,不可见节点包括:①
- JS 解析如下:
- 浏览器创建Document 对象并解析HTML ,将解析到的元素节点添加到文档中,此时
document.readystate
为loading
- HTML解析遇到没有 async 和 defer 的 script 时,将他们添加到文档中,然后执行行内或外部脚本,这些脚本会同步执行,并且在脚本下载和执行时解析器会暂停。这样就可以用
document.write()
把文本插入到输入流中。同步脚本经常简单定义函数和注册时间处理程序,他们可以遍历和操作 script 和 他们之前的文档内容 - 当解析器遇到设置了 async 属性的 script 时,开始下载脚本并继续解析文档。脚本会在它下载完成后尽快执行,但是解析器不会停下来等他下载。异步脚本禁止使用
document.write()
他们可以访问自己的 script 和之前的文档元素 - 当文档完成解析,
document.readState
变成interactive
- 所有
defer
脚本会按照在文档出现的顺序执行,延迟脚本能访问完整文档树,禁止使用document.write()
- 浏览器在
Document
对象上触发DOMContentLoaded
事件 - 此文档完全解析完成,浏览器可能还在等待如图片等内容加载,等这些内容完成载入并且所有异步脚本完成载入和执行,
document.readState
变为complete
window
触发load 事件
- 浏览器创建Document 对象并解析HTML ,将解析到的元素节点添加到文档中,此时
- 显示页面(HTML 解析过程中会逐步显示页面)
详细简版
- 从浏览器接收
RUL
到开启网络请求线程(这一部分可以展开浏览器的机制以及进程与线程之间的关系) - 开启网络线程到发出一个完整的
HTTP
请求(这一部分涉及到dns
查询,TCP/IP
请求,五层因特网协议栈等知识) - 从无服务器接受到请求到对应后台接受到请求(这部分可能涉及到负载均衡,安全拦截以及后台内部的处理等等)
- 后台和前台的
HTTP
交互,(这一部分包括HTTP
头部、响应码、报文接口、cookie
等知识,可以提下静态资源的cookie
优化, 以及编码解码, 如gzip
压缩等) - 单独拎出来的缓存问题,
HTTP
的缓存(这部分包括http
缓存头部,ETag catch-control
等) - 浏览器接收到
HTTP
数据包的解析流程(解析html
此法分析然后解析成dom
数、解析css
生成css
规则书、合并成render
树, 然后 渲染、复合layout、painting
图层的合成、GPU
绘制、 外链资源的处理、loading
和DOMContentLoaded
等) - css 的可视化格式魔性(元素的渲染规则,如包含快,控制框,
BFC
、IFC
等概念) - JS 引擎解析过程(js 解释阶段、预处理阶段、执行阶段生成的执行上下文,
VO
作用域连、回收机制等等) - 其他(可以扩展不同的只是模块,如跨域、web安全,
hybrid
模式 等等内容)