前端性能
性能API上的流程时间点(timing的整体结构)
- navigationStart: 表示从上一个文档卸载结束时的 unix 时间戳,如果没有上一个文档,这个值将和 fetchStart 相等。
- unloadEventStart: 表示前一个网页(与当前页面同域)unload 的时间戳,如果无前一个网页 unload 或者前一个网页与当前页面不同域,则值为 0。
- unloadEventEnd: 返回前一个页面 unload 时间绑定的回调函数执行完毕的时间戳。
- redirectStart: 第一个 HTTP 重定向发生时的时间。有跳转且是同域名内的重定向才算,否则值为 0。
- redirectEnd: 最后一个 HTTP 重定向完成时的时间。有跳转且是同域名内部的重定向才算,否则值为 0。
- fetchStart: 浏览器准备好使用 HTTP 请求抓取文档的时间,这发生在检查本地缓存之前。
- domainLookupStart/domainLookupEnd: DNS 域名查询开始/结束的时间,如果使用了本地缓存(即无 DNS 查询)或持久连接,则与 fetchStart 值相等
- connectStart: HTTP(TCP)开始/重新 建立连接的时间,如果是持久连接,则与 fetchStart 值相等。
- connectEnd: HTTP(TCP) 完成建立连接的时间(完成握手),如果是持久连接,则与 fetchStart 值相等。
- secureConnectionStart: HTTPS 连接开始的时间,如果不是安全连接,则值为 0。
- requestStart: HTTP 请求读取真实文档开始的时间(完成建立连接),包括从本地读取缓存。
- responseStart: HTTP 开始接收响应的时间(获取到第一个字节),包括从本地读取缓存。
- responseEnd: HTTP 响应全部接收完成的时间(获取到最后一个字节),包括从本地读取缓存。
- domLoading: 开始解析渲染 DOM 树的时间,此时 Document.readyState 变为 loading,并将抛出 readystatechange 相关事件。
- domInteractive: 完成解析 DOM 树的时间,Document.readyState 变为 interactive,并将抛出 readystatechange 相关事件,注意只是 DOM 树解析完成,这时候并没有开始加载网页内的资源。
- domContentLoadedEventStart: DOM 解析完成后,网页内资源加载开始的时间,在 DOMContentLoaded 事件抛出前发生。
- domContentLoadedEventEnd: DOM 解析完成后,网页内资源加载完成的时间(如 JS 脚本加载执行完毕)。
- domComplete: DOM 树解析完成,且资源也准备就绪的时间,Document.readyState 变为 complete,并将抛出 readystatechange 相关事件。
- loadEventStart: load 事件发送给文档,也即 load 回调函数开始执行的时间。
- loadEventEnd: load 事件的回调函数执行完毕的时间。
or
startTime
:有些浏览器实现为navigationStart
.aspx),代表浏览器开始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
事件完成的时间节点,此刻用户可以对页面进行操作,也就是JS 脚本加载执行完毕或者jQuery中的domready时间;domComplete
:html文档完全解析完毕的时间节点;loadEventStart
和loadEventEnd
分别代表onload事件触发和结束的时间节点
DOM的时间点
上图几个DOM时间点的解释:
domLoading:这是整个过程的起始时间戳,浏览器即将开始解析第一批收到的 HTML 文档字节。
domInteractive:表示浏览器完成对所有 HTML 的解析并且 DOM 构建完成的时间点。
domContentLoaded:表示 DOM 准备就绪并且没有样式表阻止 JavaScript 执行的时间点,这意味着现
在我们可以构建渲染树了。
- 许多 JavaScript 框架都会等待此事件发生后,才开始执行它们自己的逻辑。因此,浏览器会捕获
EventStart 和 EventEnd 时间戳,让我们能够追踪执行所花费的时间。
- 许多 JavaScript 框架都会等待此事件发生后,才开始执行它们自己的逻辑。因此,浏览器会捕获
domComplete:顾名思义,所有处理完成,并且网页上的所有资源(图像等)都已下载完毕,也就是说,加载转环已停止旋转。
loadEvent:作为每个网页加载的最后一步,浏览器会触发 onload 事件,以便触发额外的应用逻辑。
2.2.2 计算性能指标
可以使用Navigation.timing
统计到的时间数据来计算一些页面性能指标,比如DNS查询耗时、白屏时间、domready等等。如下:
- DNS查询耗时 = domainLookupEnd - domainLookupStart
- TCP链接耗时 = connectEnd - connectStart
- request请求耗时 = responseEnd - responseStart
- 解析dom树耗时 = domComplete - domInteractive
- 白屏时间 = domloadng - fetchStart
- domready时间 = domContentLoadedEventEnd - fetchStart
- onload时间 = loadEventEnd - fetchStart
W3C API
window.performance 是W3C性能小组引入的新的API,目前IE9以上的浏览器都支持。在Console Tab下,我们可以通过输入window.performance.timing来查询到浏览器显示一个页面,各个阶段所耗费的时间。
除了timing字段,performance还有几个字段,可以让我们对页面进行更好的分析
memory字段代表的是JS对内存的占用
navigation字段统计的是一些网页导航。
2.1. redirectCount 同源重定向的数量等
2.2. type 返回值是0,1,2,
- 0 : TYPE_NAVIGATE (用户通过常规导航方式访问页面,比如点一个链接,或者一般的get方式)
- 1 : TYPE_RELOAD (用户通过刷新,包括JS调用刷新接口等方式访问页面)
- 2 : TYPE_BACK_FORWARD (用户通过后退按钮访问本页面)
chrome API
performance
之前chorme老版本名为timeline,指的是当你的页面在浏览器运行时的性能表现,用这个performance功能去分析Response, Animation, 以及 Idle 这三个性能指标。
Begin
- 打开Chrome的匿名模式。匿名模式可以保证Chrome在一个相对干净的环境下运行。比如,你安装了许多chrome插件,这些插件可能会影响我们分析性能表现。
- 在匿名模式下打开右边这个链接,DEMO,这个网页就是我们要用来分析的DEMO。这个页面里都是很多上下移动的蓝色小方块。
- 右键检查Command+Opiton+I(Mac)或者Control+shift+I (Windows, Linux) 来打开Devtools。
- 开发使用的电脑配置普遍较高,在Performance选项卡中,对于CPU,选择4x减速。DevTools限制你的CPU,使其比平时慢4倍。
如果要确保它们在低端移动设备上运行良好,请将CPU限制设置为20x减速。
- control 条,最上面一条,有录制,刷新页面,清除结果等操作
- overview总览图,横轴是时间线,包含fps帧率,cpu占用,net网络请求,页面性能的汇总
- 火焰图,Network,Frames, Interactions, Main等
- 总结:精确到毫秒级的分析,按调用层级,事件分类的整理
在火焰图的network中 :
- HTML 文件为蓝色。
- 脚本为黄色。
- 样式表为紫色。
- 媒体文件为绿色。
- 其他资源为灰色。
1 | window.onload = function(){ |
通过分析,发现用此方法 DOM加载完成和全部加载完成耗用的时间和chrome浏览器NETWORDK面板上显示的DomContentLoaded 、Load时间基本一致,误差几ms,
所以我们基本上可以用这个方法来统计我们所做的H5网站在不同地域、不同客户端下加载H5所耗用的时间,进而逐个优化。比如DNS耗时, DOM加载耗时了
reflow(回流)
说到页面为什么会慢?那是因为浏览器要花时间、花精力去渲染,尤其是当它发现某个部分发生了点变化影响了布局,需要倒回去重新渲染, 该过程称为reflow(回流)。
在浏览器的渲染过程中(页面初始化,用户行为改变页面样式,动画改变页面样式) reflow(回流)repaint(重绘)都会大大影响web性能,尤其是h5页面。
reflow 几乎是无法避免的。现在界面上流行的一些效果,比如树状目录的折叠、展开(实质上是元素的显示与隐藏)等,都将引起浏览器的 reflow。鼠标滑过、点击……只要这些行为引起了页面上某些元素的占位面积、定位方式、边距等属性的变化,都会引起它内部、周围甚至整个页面的重新渲 染。通常我们都无法预估浏览器到底会 reflow 哪一部分的代码,它们都彼此相互影响着。