从用户输入浏览器输入url到页面最后呈现 有哪些过程?
输入网址 ☞ 解析域名 ☞ 浏览器发送HTTP请求 ☞ 服务器处理请求 ☞ 服务器返回HTML响应 ☞ 浏览器处理HTML页面 ☞ 继续请求其他资源
- 用户输入URL地址
- 浏览器解析URL解析出主机名
- 浏览器将主机名转换成服务器ip地址(浏览器先查找本地DNS缓存列表 没有的话 再向浏览器默认的DNS服务器发送查询请求 同时缓存)
- 浏览器将端口号从URL中解析出来
- 浏览器建立一条与目标Web服务器的TCP连接(三次握手)
- 浏览器向服务器发送一条HTTP请求报文
- 服务器向浏览器返回一条HTTP响应报文
- 关闭连接 浏览器解析文档
- 如果文档中有资源 重复6 7 8 动作 直至资源全部加载完毕
PerformanceTiming
window.performance是w3c提供的用来测量网页和Web应用程序的性能api。其中performance timing提供了延时相关的性能信息,可以高精度测量网站性能。
下面是每个节点的具体含义
- Prompt for unload:提示卸载,关闭掉之前开启的页面内容,在最后节点有一个
navigationStart
表示当前页面加载开始时间点 - redirect:重定向,
- app cache:应用缓存,浏览器拿到url后,首先脱机(离线)检查本地缓存有没有访问过,有则从缓存中获取,不进行后序操作。
- DNS:URL ==> ip地址
- TCP: 三次握手
- Request:请求,
requestStart
- Response:响应,
responseStart、responseEnd
- Processing:浏览器内部的处理,dom载入
domLoading
=>dom树加载完成domInteractive
=>加载资源domContentLoaded
=>dom处理完毕domComplete
,到此步浏览器的核心功能完成 - onload:加载,处理js脚本执行
优化点
- DNS,是CDN的基础,寻找最近的CDN服务器
- TCP链接时间,属于I/O操作
- 网络请求与响应时间,网络传输速度,请求包越小越少就越快
- Processing阶段,优化dom结构,避免dom树嵌套过深影响浏览器解析速度
- 缓存,浏览器和服务器端的缓存
页面性能数据重要指标
DNS查询耗时、TCP链接耗时、request请求耗时、解析dom树耗时、白屏时间、domready时间、onload 时间等,而这些参数是通过上面的performance.timing各个属性的差值组成的,计算方法如下:
- DNS查询耗时 :domainLookupEnd - domainLookupStart
- TCP链接耗时 :connectEnd - connectStart
- request请求耗时 :responseEnd - responseStart
- 解析dom树耗时 : domComplete- domInteractive
- 白屏时间 :responseStart - navigationStart
- domready时间 :domContentLoadedEventEnd - navigationStart
- onload时间 :loadEventEnd - navigationStart
NavigationTiming的目的是用于分析页面整体性能指标。如果要获取个别资源(例如JS、图片)的性能指 标,就需要使用Resource Timing API。
window.onload = function(){
setTimeout(function(){
let t = performance.timing
console.log('DNS查询耗时 :' + (t.domainLookupEnd-t.domainLookupStart).toFixed(0))
console.log('TCP链接耗时 :' + (t.connectEnd - t.connectStart).toFixed(0))
console.log('request请求耗时 :' + (t.responseEnd - t.responseStart).toFixed(0))
console.log('解析dom树耗时 :' + (t.domComplete - t.domInteractive).toFixed(0))
console.log('白屏时间 :' + (t.responseStart - t.navigationStart).toFixed(0))
console.log('domready时间 :' + (t.domContentLoadedEventEnd - t.navigationStart).toFixed(0))
console.log('onload时间 :' + (t.loadEventEnd - t.navigationStart).toFixed(0))
if(t = performance.memory){
console.log('js内存使用占比 :' + (t.usedJSHeapSize / t.totalJSHeapSize * 100).toFixed(2) + '%')
}
})
}
三次握手、四次挥手
为了保证通信的可靠性,所以才有了三次握手四次挥手。传输层协议有TCP和UDP,TCP是可靠传输,UDP是不可靠传输。TCP每发一次包,接收端都会做出响应,无论成功与否,都会通知发送端;UDP只负责发送,接收端收到与否不关心。
三次握手
- client端发送请求包,携带参数
sequence number = x
序列号 - server收到后返回链接应答,多携带参数
sequence number = y
服务器应答序列号、acknowledgment number = x+1
应答编号 - client收到服务器应答包后,会向server端发送应答包确认已收到server端应答包,携带参数
acknowledgment number = y+1
应答编号
来回告知对方收到链接请求和应答是为了避免半链接的存在。
数据传输
每次client端发送请求,序列号和应答号都会在不停的增长,每次请求都会携带,以确定网络传输过程的可靠性。每次请求client端都会发送请求包,server端收到后会告诉client端收到请求包。
链接建立之后,client端和server端都会消耗一定的资源(CPU、端口、内存)来维护链接。故当链接不需要时就要删除链接来释放这些资源,避免崩溃。
四次挥手
TCP半链接:一端认为TCP链接是通的,另一端认为TCP链接是断开的,这就是TCP半链接。这就造成了资源的浪费。
无论是建立连接还是断开连接都是client端发起的。
- client端发送关闭链接的请求
- server端收到请求后,会告诉client端收到请求,并检查当前链接工作是否已完成
- server端无未完成工作后会再次发送一个应答,告知client端server端可以断开链接
- client端收到server端的第二次应答后才会向server端发送最终的关闭链接
关闭TCP链接需要确认两端对方将工作完成后才能关闭链接
缓存机制
缓存的优点:
- 减少相应延迟
- 减少网络请求带宽的消耗
浏览器缓存机制 — 第一次请求
浏览器缓存机制 — 再次请求
Etag/If-None-Match策略
Etag
web服务器相应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则有服务器决定),唯一标识为ID。
If-None-Match
当资源过期是(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求是带上头If-None-Match
(Etage值)。web服务器收到请求后发现有头If-None-Match
则与被请求资源的相应校验串进行比对,决定返回200或304。
Last-Modified/If-Modified-Since策略
Last-Modified
标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间。
If-Modified-Since
当资源过期是(使用Cache-Control标识的max-age),发现资源具有Last-Modified声明,则再次向web服务器请求是带上If-Modified-Since,表示请求时间。web服务器收到请求后发现有头If-Modified-Since则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被修改过,则相应整片资源内容(写在响应消息包体内),HTTP200;若最后U修改时间教旧,说明资源无新修改,则相应HTTP304(无需包体,节省浏览),告知浏览器继续使用保存的cache。