总体分为以下几个过程:
- DNS域名解析
- TCP三次握手连接
- 发送HTTP请求
- 服务器处理请求返回报文
- 浏览器解析渲染
TCP/IP模型:应用层--传输层--网络层--数据链路层
发送端从应用层往下走,接收端从数据链路层往上走。
DNS域名解析
DNS服务器将域名解析成对应的服务器IP地址。
解析过程: . -> .com -> google.com. -> www.google.com.
从右向左,根域、顶级域、二层域、子域、主机名。
这步拿到服务器IP地址。
TCP三次握手连接服务器
TCP是传输层协议。
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认; SYN:同步序列编号(Synchronize Sequence Numbers) 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态; 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手.
这步与服务器建立了连接。
发送HTTP请求
连接到服务器,可以发送请求。可以在浏览器Network中查看报文首部(请求首部/响应首部)、响应主体等信息。
服务器处理请求返回报文
web服务器如Apache/Nginx等处理请求(html/js/php/sql)并把结果发返回给客户端。
HTTP状态码
- 200 - 请求成功
- 201 - 告诉服务器创建一个文件,最后服务器创建成功返回的状态码
- 204 - 对于某些请求(PUT或DELETE等),服务器不想处理可以返回空,并用204状态码告知
- 301 - 资源(网页等)被永久转移到其它URL【永久重定向】
- 302 - 临时转移,现在主要用307
- 307 - 临时重定向,用于服务器负载均衡
- 304 - 设置HTTP的协商缓存
- 400 - 传给服务器的参数错误
- 401 - 无权限访问
- 404 - 请求的资源(网页等)不存在
- 500 - 内部服务器错误
- 503 - 由于临时的服务器维护或者过载【服务器超负荷】
这步拿到服务器的资源文件。
浏览器解析渲染
浏览器:运行在操作系统上的一个应用程序【多进程】
进程process:创建一个应用程序,启动一个进程来执行任务代码并分配内存空间
线程thread:一个进程中会包含0到多个线程,同时做很多事情
浏览进程包括:浏览器进程、GPU进程、插件进程、渲染进程、缓存进程、网络进程
注:浏览器是多进程的,但是页面渲染是单线程的。
从服务器拿到资源文件后,浏览器开始渲染页面。过程如下:
- 构建DOM树(解析HTML)和CSS规则树(解析CSS); 字节-->字符-->标签-->节点-->构建树
- 构建渲染树。渲染树由DOM树、CSSOM树合并而成,与DOM树不同,没有display为none和<head>元素等不必显示的节点。
- 根据渲染树在当前视口进行结构和位置的计算,重排/重绘。
重绘:改变元素的颜色属性,不会重新触发布局,会触发样式计算和绘制。
重排:改变元素的尺寸位置,重新进行样式计算、布局、绘制以及后面的所有流程。
重排情况
- 删除或者添加节点
- 元素尺寸和位置改变
- 元素内容改变---一个文本被另一个不同尺寸的图片替代
- 页面渲染初始化
- 浏览器窗口尺寸改变(resize事件)
注:
- 重排必然引起重绘,反之不一定。
- 重排、重绘,以及JS运行都在主线程,会出现抢占执行时间的问题。
(页面以60帧每秒的刷新率才不会让页面感到页面卡顿。当一帧的时间内布局、绘制结束后,还有剩余时间就会让JS拿到主线程的使用权,如果JS执行时间过长,就会在下一帧开始时JS没有及时归还主线程,导致下一帧没有按时渲染,就会出现页面卡顿。)
动画优化方式
requestAnimationFrame 在每一帧被调用,通过API回调把JS切割成小任务,在每一帧事件用完前在暂停JS的执行、归还主线程,下一帧开始布局和绘制就可以按时进行。
transfrom 不会进行布局和绘制,直接运行在合成器线程和栅格进程,不占用主线程。
如何减少重绘与重排?