衡量性能的核心指标
衡量指标
假如没有相应的指标来衡量,那么就无法准确判断出性能优化的效果。Google为此给出了三大核心指标:
- 最大内容绘制(LCP)
- 首次输入延迟(FID)
- 累计布局偏移(CLS)
除此之外还有一些重要的衡量指标
- 首次内容绘制(FCP)
- 首字节时间(TTFB)
最大内容绘制
首次加载时首屏中最大的图像块或文本块完成渲染的时间。相比较首次内容绘制,最大内容绘制更具代表性。
首次输入延迟
首次输入延迟是指用户第一次与页面交互到浏览器做出响应的时间,更短的延迟意味着更好的交互性。
累计布局偏移
累计布局偏移是指整个页面生命周期内发生的所有意外布局偏移的累计,更小的累计布局偏移就表示着页面视觉稳定性越好。
首次内容绘制
首次加载到页面任意部分渲染完成的时间,但是最快绘制完成任意内容块并不能表示最快绘制完成首屏内容,通常最大内容绘制时间比首次内容绘制时间更有代表性。
首字节时间
Time to First Byte (TTFB) 是衡量的是资源请求的第一个字节到响应的第一个字节到达的时间,是衡量网络情况和web服务器响应能力的重要指标。
衡量工具
浏览器开发者工具
衡量性能指标最简单最方便的工具就是浏览器开发者工具
查看三大核心指标
打开Edge开发者工具,在绘制一栏开启核心网页指标
查看TTFB
在网络一栏,打开页面html文件的详情页(通常是第一个),点击计时一栏
在这里不仅能看到TTFB,还可以看到其他请求响应相关的耗时,例如阻塞耗时。在这一块我更推荐火狐浏览器开发者版浏览器,可以查看的信息更多。
Performance API
Timing API
window.performance是一个包含一些页面性能指标的对象,在其timing属性中包含着页面生命周期的许多时间戳,可以通过时间戳的计算来算出某些事件的时长。
属性说明:
startTime
:有些浏览器实现为navigationStart
,代表浏览器开始unload前一个页面文档的开始时间节点。比如我们当前正在浏览baidu.com,在地址栏输入google.com并回车,浏览器的执行动作依次为:unload当前文档(即baidu.com)->请求下一文档(即google.com)。navigationStart的值便是触发unload当前文档的时间节点。如果当前文档为空,则navigationStart的值等于fetchStart。
redirectStart
和redirectEnd
:如果页面是由redirect而来,则redirectStart和redirectEnd分别代表redirect开始和结束的时间节点;
unloadEventStart
和unloadEventEnd
:如果前一个文档和请求的文档是同一个域的,则unloadEventStart和unloadEventEnd分别代表浏览器unload前一个文档的开始和结束时间节点。否则两者都等于0;
fetchStart
是指在浏览器发起任何请求之前的时间值。在fetchStart和domainLookupStart之间,浏览器会检查当前文档的缓存;
domainLookupStart
和domainLookupEnd
分别代表DNS查询的开始和结束时间节点。如果浏览器没有进行DNS查询(比如使用了cache),则两者的值都等于fetchStart;
connectStart
和connectEnd
分别代表TCP建立连接和连接成功的时间节点。如果浏览器没有进行TCP连接(比如使用持久化连接webscoket),则两者都等于domainLookupEnd;
secureConnectionStart
:可选。如果页面使用HTTPS,它的值是安全连接握手之前的时刻。如果该属性不可用,则返回undefined。如果该属性可用,但没有使用HTTPS,则返回0;
requestStart
代表浏览器发起请求的时间节点,请求的方式可以是请求服务器、缓存、本地资源等;
responseStart
和responseEnd
分别代表浏览器收到从服务器端(或缓存、本地资源)响应回的第一个字节和最后一个字节数据的时刻;
domLoading
代表浏览器开始解析html文档的时间节点。我们知道IE浏览器下的document有readyState属性,domLoading的值就等于readyState改变为loading的时间节点;
domInteractive
代表浏览器解析html文档的状态为interactive时的时间节点。domInteractive并非DOMReady,它早于DOMReady触发,代表html文档解析完毕(即dom tree创建完成)但是内嵌资源(比如外链css、js等)还未加载的时间点;
domContentLoadedEventStart
:代表DOMContentLoaded事件触发的时间节点: 页面文档完全加载并解析完毕之后,会触发DOMContentLoaded事件,HTML文档不会等待样式文件,图片文件,子框架页面的加载(load事件可以用来检测HTML页面是否完全加载完毕(fully-loaded))。
domContentLoadedEventEnd
:代表DOMContentLoaded事件完成的时间节点,此刻用户可以对页面进行操作,也就是jQuery中的domready时间;
domComplete
:html文档完全解析完毕的时间节点,注意这会包含script执行的时间;
loadEventStart
和loadEventEnd
分别代表onload事件触发和结束的时间节点
常用的测量时间。
DNS查询耗时 = domainLookupEnd - domainLookupStart TCP链接耗时 = connectEnd - connectStart request请求耗时 = responseEnd - responseStart 解析dom树耗时 = domComplete - domInteractive 白屏时间 = domContentLoadedEventEnd - fetchStart domready可操作时间 = domContentLoadedEventEnd - fetchStart onload总下载时间 = loadEventEnd - fetchStart
注意 最好设置一个定时器,延迟一段时间后再获取时间戳,因为某些属性在script标签执行时可能还没准备好,例如domComplete。
User Timing API
User Timing API 是基于时间的通用度量 API,你可以使用它任意标记时间点,然后测量这些标记之间持续的时间。
function wait() { return new Promise((resolve) => { setTimeout(() => { resolve() }, 1000) }) } async function fn() { performance.mark('myTask:start'); await wait() // 记录任务运行后的时间。 performance.mark('myTask:end'); // 测量任务开始和结束之间的增量 console.log(performance.measure('myTask', 'myTask:start', 'myTask:end')); }
关于User Timing更多API见使用用户计时 API - Web API |MDN (mozilla.org)
资源加载时间
performance.getEntries()
会返回一个包含所有资源加载信息的数组。Lighthouse
测量页面性能指标更好的方法是使用测量工具,LightHouse是其中一个比较有代表性的工具,它不仅可以测量页面性能,还可以给出修改意见。
参考
《大型网站性能优化实战》