首先我们从大的方面说一下吧,后边细节在补充
预请求
DNS解析
TCP链接
HTTP请求
服务器响应http
断开连接
浏览器解析
渲染呈现
目的是将我们输入的域名解析到对应的IP地址,整个过程是递归查询的,查询的途径有:
原因是浏览器的同源策略(协议、域名、端口)
TCP提供可靠的传输协议、UDP提供不可靠的传输协议
三次握手 1.客户端向服务器发送SYN标志的数据包(表示客户端希望建立一个连接)能听见不 2.服务端发送带有SYN+ACK(代表应答) 的应答包(确认包+序列号) 能听见 你能听见不 3.客户端发送ACK的应答数据包(确认序列号) 我可以
为什么需要三次? 只有三次才会同步双方序列号,只有三次可以避免重复连接
四次挥手 1.客户端发送带FIN=1,seq=u数据包 2.服务器进入Close-wait状态,发送ack=1,seq=u+1 (客户端到服务端的连接释放,但是服务端到客户端连接存在) 3.服务器发送释放报文FIN=1,ack=u+1 4.客户端应答ack=w+1,seq=u+1,发送完毕等待2msl,然后关闭
当建立起T CP请求之后,服务端会持续监听,客户端发送请求,服务器响应请求,这就是http的主要特点,遵循客户端、服务端的模型
http1.0,1.0中,每一对 http请求都会打开一个TCP连接,
通过设置Connection头部为keep-alive的方式,实现了TCP的复用,语义可读 但是由于服务器需要依次处理,就导致了单一链接上多个请求时,有一个请求处理缓慢,就会造成对头阻塞,为了提高性能,浏览器一般会开多个请求(通常限制为6个)
流的概念:一个流代表一个单独的双向通道,每个请求和响应都可以映射到一个流上,类似一个有身份的管道
帧的概念:数据以帧来传输,是最小的通信单位,每个帧关联到特定的流,多帧可以乱序发送,并根据流重新组装
【请求响应映射到流,帧关联到特定的流】
⚠️: 一个TCP链接可以承载多个并行的流
根据type不同而又不同的结构
UDP+QUIC协议(处理错误)实现更快更可靠的传输
由于协议无任何状态,前后的连接之间没有任何的关系,那么用户在同一个网站操作,服务器如何识别呢?这就因此诞生了cookie 服务器返回数据,通过在响应头中添加Set-Cookie,浏览器保存cookie,后期发起请求的时候带上cookie。由于cookie是浏览器自动识别保存并发送的,默认请求浏览器关闭就会删除,但是我们也可以通过设置Expires超时时间或者有效期
由于网站设置cookie 之后,符合请求的连接都会被自动带上cookie,于是就造成了一种安全漏洞(CSRF 跨站伪造),当然这种漏洞可以可以通过检查请求头中的referer,但是这个字段有可能也被篡改,一般最合适的解决方式就是,使用其他方式校验用户登录态,比如token
规定有效期内直接使用缓存 使用方式:1.服务器通过设置Expires,Cache-control和客户端约定缓存时长,2.符合缓存条件,浏览器响应200
和服务器协商是否使用缓存 使用方式:1.服务器设置If-Modified-Since和If-None-Match,和客户端约定协商缓存的值,2.有效期过了之后,浏览器讲缓存信息中的Etag、Last-Modified 信息,分别使用If-Modified-Since和If-None-Match设置请求头,提交给服务器。3.若最新数据和缓存一致,则服务器响应304,将从浏览器缓存读取数据,否则返回最新数据并缓存
为了提高效率,浏览器会启动一个预解析器率先下载CSS和JS文件,解析过程中遇到JS代码,需要暂停,等待下载完成之后继续执行全局代码,然后再执行解析HTML 渲染主线程-----解析HTML 预解析线程----浏览----解析 网络线程 -----下载CSS
大部分时候,DOM树和布局树不是一一对应的,比如display:none的节点没有几何信息,不会生成到布局树,还有伪元素、 匿名行盒、匿名块盒等等
浏览器会自行决定进行分层,可以使用属性will-change:transform 进行手动分层
为每一层单独生成绘制指令
由于视口的关系,有些图层会很大,不便全部绘制,于是就有了图块的概念,将每一层分为多个小的区域,合成线程会将图层划分为图块(tile),这些图块的大小通常是256x256或者512x512
一旦所有图块都被光栅化,合成线程就会生成一个绘制图块的命令——“DrawQuad”,然后将该命令提交给浏览器进程。紧接这会在内存中绘制并将其展示。
输入->UI线程判断->网络线程->网络线程发起请求->响应HTML->网络进程解析->判断可以渲染->通知UI线程->寻找或启动渲染进程->[浏览器进程<=IPC通信确认=>渲染器进程]->渲染器->加载渲染->IPC通知浏览器进程已加载