先进行 URL
解析,看看输入的内容是否符合 URL
规则(解析 URL
提取出协议、域名、端口号,对于一些特殊字符,在传递的时候须要进行编码解码)。css
encodeURI
、decodeURI
能够对中文、空格等编码解码,适用于 URL
自己encodeURIComponent
、decodeURIComponent
范围更广,会编码解码一些特殊字符如 :/?=+@#$
,适用于给参数编码解码URL
符合规则,浏览器进程会经过进程通讯将 URL
请求发送给网络进程,网络进程会依次查找 Memory Cache
、Disk Cache
中是否有缓存内容,有且没过时则使用,不然则发送网络请求。html
网络请求第一步就是先进行 DNS
解析,获取请求域名服务器的 IP
地址。前端
什么是
DNS
解析,每台计算机都有一个惟一IP
地址,可是IP
地址不方便记忆,因此采用更方便记忆的网址去查找其余计算机,将网址转换成IP
地址的过程就是DNS
解析。webpack
域名解析是一个递归查询 + 迭代查询的过程。git
host
文件中查找ISP
互联网服务提供商缓存,好比 114.114.114.114
,DNS
服务器进行迭代查询:.
根 DNS
服务器 -> .com
顶级服务器 -> 主域名服务器 -> ...,直到服务器返回对应的 IP
DNS
负载均衡:github
网站对应的
IP
不止一个,DNS
能够根据每台机器的负载量、距离用户的距离等返回一个合适的服务器IP
给用户,这个过程就是DNS
负载均衡,又叫作DNS
重定向。CDN
就是利用DNS
的重定向技术,DNS
会返回一个用户最接近的点的IP
给用户。web
拿到 IP
后,(检查当前域名是否达到 TCP
链接上限),经过三次握手进行 TCP
链接面试
三次握手:算法
SYN
包和初始序号 seq = x
给服务端,此时客户端状态为 SYN-SENT
SYN
包后,将标识位 SYN
和 ACK
置为1,确认序号 ack = x + 1
, 初始序号 seq = y
发送给客户端,此时服务端状态为 SYN-RECEIVED
ACK
置为1, 确认序号 ack = y + 1
, 本身的序号 seq = x + 1
, 发送给服务端,服务端收到后也将状态切换为 ESTABLISHED
三次握手抽象版:浏览器
seq
序号,用来标识从TCP
源端向目的端发送的字节流,发起方发送数据时对此进行标记ack
确认序号,只有ACK
标志位为1时,确认序号字段才有效,ack=seq+1
标识位:
ACK
:确认标识,用于表示对数据包的成功接收。SYN
:同步标识,表示 TCP
链接已初始化,发起一个新链接。FIN
:完成标识,释放一个链接,用于拆除上一个 SYN
标识。一个完整的TCP链接过程必定会有 SYN
和 FIN
包。为何不能两次握手?
TCP
的特色的可靠传输,服务端和客户端都须要可靠传输,就须要确认双方的发送和接收能力,第一次握手确认了客户端的发送能力,第二次确认了服务端的发送和接收能力,第三次确认了客户端的接收能力
两次握手,服务器不能肯定客户端已经收到了确认请求,不能确认是否创建好了链接。服务器认为创建好了链接,发送数据包,结果发的包客户端没收到,那么攻击服务器就很容易了,只发包不收包。
TCP
和 UDP
的区别:
TCP
是一个面向链接的、可靠的、基于字节流的传输层协议,TCP
会精准记录哪些数据发送了,哪些数据被对方接收了,哪些没有被接收到,并且保证数据包按序到达,不容许半点差错。这是有状态
, 当意识到丢包了或者网络环境不佳,TCP
会根据具体状况调整本身的行为,控制本身的发送速度或者重发。这是可控制
。UDP
是一个面向无链接的传输层协议,无状态
、不可控
。TCP 链接创建以后,浏览器端会构建请求行、 请求头等信息,并把和该域名相关的 Cookie 等数据附加到请求头中,而后向服务器发送构建的请求信息。若是是 HTTPS
,还须要进行 TSL
协商。
服务器检查 HTTP
请求头是否包含缓存验证信息进行协商缓存
:
Last-Modified
和 If-Modified-Since
:
Last_Modified
表示本地文件的最后修改时间,If-Modified-Since
会将Last-Modified
的值发送给服务器询问该资源是否有更新,若是有更新就会将新的资源发送回来,不然返回304
状态码,表明资源无更新,继续使用缓存文件。
Last-Modified
弊端:
Last-Modified
修改,服务器不能命中缓存。Last-Modified
的值并不会修改,会返回304
,浏览器就会是本身的缓存 。ETag
和 If-No-Match
ETag
是文件指纹,If-No-Match
会将ETag
发送给服务器,查询该资源ETag
是否变更,有变更的话就将新的资源发送回来。ETag
优先级高于Last-Modified
。
若是什么缓存都没设置,浏览器一般会响应头中的 Date
减去 Last-Modified
值的 10% 做为缓存时间。
状态码用于表示服务器对请求的处理结果
1xx
:指示信息——表示请求已经接受,继续处理
100 Continue
通常在发送 post
请求时,已发送了 http header
以后服务端返回此信息,表示确认,以后发送具体参数信息。2xx
:成功
200 OK
正常返回信息201 Created
请求成功而且服务器建立了新的资源202 Accepted
服务器已接受请求,但还没有处理3xx
:重定向
301 Moved Permanently
永久重定向302 Found
临时重定向303 See Other
临时重定向,且老是使用 GET
请求新的 URI
304 Not Modified
请求内容未改动,走缓存4xx
:客户端错误
400 Bad Request
服务器没法理解请求格式401 Unauthorized
请求未受权403 Forbidden
禁止访问404 Not Found
找不到与 URI
相匹配的资源5xx
:服务器错误。
500 Internal Server Error
服务器内部错误503 Service Unavailable
服务器暂时没法处理请求数据传输完后,若是请求头或响应头里没有 connection: keep-alive
,则须要四次挥手断开 TCP
链接,不然会保持链接通道,这样下一次在发送请求,就无需再次TCP三次握手了,节省了网络通讯时间。
http1.0
中默认Connection
并非keep-alive
,须要手动处理,可是HTTP1.1
以后,Connection:keep-alive
已经被列入了规范,如今基本都是默认就是长链接,前提是同一个源,向不一样源发送请求要从新创建通道。
四次挥手:
FIN
,用来关闭客户端到服务端的数据传输,告诉服务端我不会给你发送数据了FIN
包后,发送一个 ACK
给客户端,确认序号为收到序号 + 1FIN
,用来关闭服务端到客户端的数据传输,告诉客户端我不会给你发数据了FIN
后,发送一个 ACK
给服务端,确认序号为收到序号 + 1,完成四次挥手四次挥手抽象版:
四次握手后,客户端还会等待 2MSL
(MSL:最长报文段寿命,通常2min) 的时间,为了保证客户端发送的 ACK
报文可以到达服务器,由于这个报文可能会丢失,服务器收不到确认会超时重传 FIN
+ ACK
报文段,客户端能在 2MSL
时间内收到这个重传的报文段,而后客户端从新确认。
为何链接的时候是三次握手,关闭的时候倒是四次挥手?
SYN
链接请求报文后,能够直接发送 SYN + ACK
报文FIN
报文时,极可能并不会当即关闭链接,因此只能先回复一个 ACk
报文,告诉客户端你发的 FIN
报文我收到了,只有等服务端全部的报文发送完了,我才能发送 FIN
报文,所以不能一块儿发送,因此须要四次。gzip
压缩后的文件则进行解压缩,若是响应头 Content-type
为 text/html
,则开始解析 HTML
HTML Parser
对 HTML
文件进行处理,根据 HTML
标记关系构建 DOM
树。 - 解析过程当中遇到图片、link
、script
会启动下载。 - script
标签会阻塞 DOM
树的构建,因此通常将 script
放在底部,或者添加 async
、defer
标识。 - css
下载时异步,不会阻塞浏览器构建 DOM
树,可是会阻塞渲染,在构建布局树时,会等待 css
下载解析完毕后才进行。
CSS
样式表转化为浏览器能够理解的 styleSheets
,转换样式表中的属性使其标准化em => px; bold => 700
。DOM
树和 styleSheets
构建布局树,计算出元素的布局信息,display: none
不可见节点以及 head
这种不可见标签不会插入到布局树里
DOM
树、构建 CSSOM
树、构建树并非严格的前后顺序,为了让用户能尽快看到网页内容,都是并行推动的position: fixed/absolute
、z-index:2
、filter: blue(5px)
、opacity: .5
等拥有层叠上下文属性的元素会进行分层、或者内容须要裁减GPU
加速生成,渲染进程把生成图块的指令发送给 GPU
进程,GPU
生成最终的位图并保存在内存之中优化
CSS
下载到客户端,充分利用 HTTP
多请求并发机制,且 CSS
下载并不会阻塞渲染,style、link、@import
放到页面顶部JS
加载阻塞渲染,添加 async、defer
标识,标签放到页面底部DOM
的回流和重绘
async
和defer
都是异步的,使用async
标志的脚本文件一旦加载完成,会当即执行;而使用了defer
标记的脚本文件,须要在DOMContentLoaded
事件以前执行。
重绘:元素样式的改变,可是宽高、大小、位置等不变,好比:
color
、background
、visibility
等
回流:元素的大小或者位置发送了变化,触发了页面的从新布局,甚至调用方法或属性
getComputedStyle
、clientWidth
,为了保证获得的结果是即便性
和准确性
,致使布局树从新计算布局和渲染。
优化策略:
table
布局,由于一个小改动可能会形成整个 table
的从新布局documentFragment
操做 dom
,操做完成后再添加到文档中position
属性为 absolute
、fixed
元素上,脱离文档流,单独渲染区域CSS3
硬件加速, transform
、opacity
等属性会触发 GPU
加速,不会引起回流和重绘,可是过多使用可能会占用大量内存,性能消耗严重flush
队列,而后一次性清空。DNS
预解析CDN
,DNS
负载均衡<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href="//g.alicdn.com" />
复制代码
web
服务器、资源服务器、数据服务器,增长 HTTP
并发性TCP
的三次握手和四次挥手:HTTP1.1默认开启的 Connection: keep-alive
webpack
对传输内容进行压缩GZIP
压缩,通常能压缩 60%
左右HTTP
请求的次数base64
,可是可能会形成图片大小增长 1/3
HTTP1.1
虽然在串行请求能够经过 Connection: keep-alive
复用同一个 TCP
链接,若是是并行发送多个请求,会创建多个链接,可是浏览器通常限制会限制同一域名下最多同时能够创建6个链接。
TCP
发出下一个请求,因此会受到前面请求的阻塞。多路复用:容许同时经过单一的 HTTP2.0
链接发起的多重请求 - 响应消息,链接通道是共享的
HTTP2.0
的传输是基于二进制帧的,每一个 TCP
链接中,都有多个双向流通的流,每一个流都有独一无二的标识和优先级,而流就是由二进制帧组成的。二进制帧会标识本身是属于哪一个流的,因此这些流能够交错传输,在接收端根据帧头组装成完整的信息,解决线头堵塞的问题。
头部压缩:HTTP1.x
的 header
中带有大量的信息,每次都要重复发送,HTTP2.0
使用 HPACK
算法对 header
数据进行压缩,减小须要传输的 header
大小,通信双方各自缓存一个头部字典表,能够差别化更新头部,减小须要传输数据的大小