W3C 对浏览器的实现标准如下图所示,回答了该问题
- 重定向
- 缓存
- DNS 解析
- TCP 连接
- HTTP 请求
- HTTP 响应
- 处理文档
- 装载
- 渲染页面
浏览器实现标准:performance.timing 属性介绍
属性说明:
是一个无符号long long 型的毫秒数 表示某个时间的unix时间戳
- PerformanceTiming.navigationStart:浏览器上下文上一个页面unload的时间戳,如果没有上一个文档,这个值会和PerformanceTiming.fetchStart相同
- PerformanceTiming.unloadEventStart:unload事件抛出时的时间戳,如果没有上一个文档或者上一个文档与重定向中的一个不同源 这个值回返回0
- PerformanceTiming.unloadEventEnd: unload事件结束的时间戳,如果没有上一个文档或者上一个文档与重定向的下一个文档不同源 这个值回返回0
- PerformanceTiming.redirectStart :第一个HTTP重定向开始时的UNIX时间戳。如果没有重定向,或者重定向中的一个不同源,这个值会返回0
- PerformanceTiming.redirectEnd:最后一个HTTP重定向完成时的UNIX时间错,如果没有重定向,或者重定向中的一个不同源,这个值会返回0
- PerformanceTiming.fetchStart:浏览器准备好使用HTTP请求来获取文档的UNIX时间戳,这个时间点会在检查任何应用缓存之前
- PerformanceTiming.domainLookupStart: 域名查询开始的UNIX时间戳,如果使用了持续连接(persistent connection)或者这个信息存储到了缓存或者本地资源上,这个值将和Performance.fetchStart 一致
- PerformanceTiming.domainLookupEnd: 域名查询结束时间戳,如果使用了持续连接(persistent connection)或者这个信息存储到了缓存或者本地资源上,这个值将和Performance.fetchStart 一致
- PerformanceTiming.connectStart: 返回HTTP请求开始向服务器发送的Unix时间戳,如果是用来持续连接,则返回值等用于fetchStart
- PerformanceTiming.connectEnd:浏览器与服务器连接建立(握手和认证过程结束)的毫秒时间戳。
- PerformanceTiming.secureConnectionStart: 浏览器与服务器开始安全连接的握手时的时间戳,如果当前网页不要求安全连接,则返回0
- PerformanceTiming.requestStart: 浏览器向无武器发出HTTP请求时(或开始读取本地缓存)时的时间戳。
- PerformanceTiming.responseStart: 浏览器从服务器收到(或东本地缓存读取)第一个字节时的Unix毫秒时间戳,如果传输层在开始请求之后失败并且连接被重开,该属性将会被数制成新的请求的相对应的发起时间。
- PerformanceTiming.responseEnd: 浏览器从服务器收到(或重本地缓存读取,或从本地资源读取)最后一个字节时(如果在此之前HTTP连接已经关闭,则返回关闭时)的时间戳
- PerformanceTiming.domLoading: 返回当前网页DOM结构开始解析时(即Document.readyState属性变为“loading”、相应的 readystatechange事件触发时)的Unix毫秒时间戳。
- PerformanceTiming.domInteractive: 当前网页结构(DOM树生成)结束解析,开始加载内嵌资源时(即Document.readyState属性变为“interactive”、相应的readystatechange事件触发时)的Unix毫秒时间戳
- PerformanceTiming.domContentLoadedEventStart: 解析器发送DOMContentLoaded 事件,纯HTML被完全加载以及解析时(而不必等待样式表,图片或者子框架完成加载)时的Unix毫秒时间戳
- PerformanceTiming.domContentLoadedEventEnd: 所有需要立即执行的脚本已经被执行(不论执行顺序)时的Unix毫秒时间戳
- PerformanceTiming.domComplete: 当前文档解析完成,即Document.readyState 变为 'complete'且相对应的readystatechange 被触发时的Unix毫秒时间戳
- PerformanceTiming.loadEventStart: 该文档下,load事件被发送时的Unix毫秒时间戳。如果这个事件还未被发送,它的值将会是0
- PerformanceTiming.loadEventEnd: load事件结束,即加载事件完成时的Unix毫秒时间戳。如果这个事件还未被发送,或者尚未完成,它的值将会是0.
——————————
1. performance 应用
- 关键时间节点
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) + '%')
}
})
}
- 实现一个sortTiming 函数, 满足:按照时间顺序暂时,计算所有时间戳跟最早的时间戳的差值
Object.entries(performance.timing.toJSON()).filter(item=>item[1]).sort((a,b)=>a[1]-b[1]).map((item, index, arr)=>[...item, item[1] - arr[0][1]])
2. DNS 详解
DNS (Domain Name System) 域名系统,用于将域名转成IP (1对多)
域名解析
- 首先浏览器先检查本地hosts文件是否有这个网址应色号关系,如果有就调用这个IP地址映射,完成域名解析
- 如果没有找到则会查找本地DNS解析器缓存,如果查到则返回
- 如果还是没有找到则会查找本地DNS服务器,如果查找到则返回
- 最后迭代查询,按根域名服务器 -> 顶级域 .com ->第二层域 baidu.com -> 子域 www.baidu.com 的顺序找到IP地址
3. TCP
seq 表示包的编号, SYN 同步序列编号, ACK 确认字符 ( + 1)
其他知识点
document.readyState
- loading / 正在加载 document 仍在加载。
- interactive / 可交互 文档已被解析,"正在加载"状态结束,但是诸如图像,样式表和框架之类的子资源仍在加载。
- complete / 完成 文档和所有子资源已完成加载。表示 load 状态的事件即将被触发。
当这个属性的值变化时,document 对象上的readystatechange 事件将被触发。