代码质量是一切的基础,可读性高的代码问题自然少。
正文开始
此前分享给服务端的性能分析
(1)接口性能调优的方式方法,你知道多少?
(2)性能测试中主要术语及相关指标计算
(3)服务端性能瓶颈定位思路,就怕你不清楚
1.关键点
分页面、区域、浏览器、性能指标
页面的性能指标详解:
白屏时间(first Paint Time)——用户从打开页面开始到页面开始有东西呈现为止
首屏时间——用户浏览器首屏内所有内容都呈现出来所花费的时间
用户可操作时间(dom Interactive)——用户可以进行正常的点击、输入等操作,默认可以统计domready时间,因为通常会在这时候绑定事件操作
总下载时间——页面所有资源都加载完成并呈现出来所花的时间,即页面 onload 的时间
确定统计起点:
我们需要在用户输入 URL 或者点击链接的时候就开始统计,因为这样才能衡量用户的等待时间。高端浏览器Navigation Timing接口;普通浏览器通过 cookie 记录时间戳的方式来统计,需要注意的是 Cookie 方式只能统计到站内跳转的数据。
2.如何统计性能指标的时间
2.1白屏时间
公式:
白屏时间=开始渲染时间(首字节时间+HTML下载完成时间)+头部资源加载时间
如何获取:
chrome 高版本:
window.chrome.loadTimes().firstPaintTime loadTimes获取的结果
{
connectionInfo: “http/1”,
finishDocumentLoadTime: 1422412260.278667,
finishLoadTime: 1422412261.083637,
firstPaintAfterLoadTime: 1422412261.094726,
firstPaintTime: 1422412258.085214,
navigationType: “Reload”,
npnNegotiatedProtocol: “unknown”,
requestTime: 0,
startLoadTime: 1422412256.920803,
wasAlternateProtocolAvailable: false,
wasFetchedViaSpdy: false,
wasNpnNegotiated: false
}
所以计算公式:
(chrome.loadTimes().firstPaintTime - chrome.loadTimes().startLoadTime)*10
其他浏览器:
大部分浏览器没有特定函数,必须想其他办法来监测。仔细观察 WebPagetest 视图分析发现,白屏时间出现在头部外链资源加载完附近,因为浏览器只有加载并解析完头部资源才会真正渲染页面。基于此我们可以通过获取头部资源加载完的时刻来近似统计白屏时间。尽管并不精确,但却考虑了影响白屏的主要因素:首字节时间和头部资源加载时间(HTML下载完成时间非常微小)。
有一个点:mod_36ad799.js等几个js为什么会在hm.js之前下载?html代码如下
这貌似与我们熟知的脚本阻塞解析不符啊,理应是脚本插入hm.js在先,导致DOM树改变,重新绘制DOM树,然后继续往下解析……原因是现在的浏览器对这个过程做了优化:
处理脚本及样式表的顺序(The order of processing scripts and style sheets)
脚本
web的模式是同步的,开发者希望解析到一个script标签时立即解析执行脚本,并阻塞文档的解析直到脚本执行完。如果脚本是外引的,则网络必须先请求到这个资源——这个过程也是同步的,会阻塞文档的解析直到资源被请求到。这个模式保持了很多年,并且在html4及html5中都特别指定了。开发者可以将脚本标识为defer,以使其不阻塞文档解析,并在文档解析结束后执行。Html5增加了标记脚本为异步的选项,以使脚本的解析执行使用另一个线程。
预解析(Speculative parsing)
Webkit和Firefox都做了这个优化,当执行脚本时,另一个线程解析剩下的文档,并加载后面需要通过网络加载的资源。这种方式可以使资源并行加载从而使整体速度更快。需要注意的是,预解析并不改变Dom树,它将这个工作留给主解析过程,自己只解析外部资源的引用,比如外部脚本、样式表及图片。
样式表(Style sheets)
样式表采用另一种不同的模式。理论上,既然样式表不改变Dom树,也就没有必要停下文档的解析等待它们,然而,存在一个问题,脚本可能在文档的解析过程中请求样式信息,如果样式还没有加载和解析,脚本将得到错误的值,显然这将会导致很多问题,这看起来是个边缘情况,但确实很常见。Firefox在存在样式表还在加载和解析时阻塞所有的脚本,而Chrome只在当脚本试图访问某些可能被未加载的样式表所影响的特定的样式属性时才阻塞这些脚本。
所以就得到了上面的那个结果
看看IE的处理
回归正题,普通浏览器需要获取两个时间:开始渲染时间和头部资源加载时间:
开始渲染时间:
需要借助浏览器的navigator timing属性performance;window.performance.timing(Navigation timing性能时间线) 相关属性:
// 在同一个浏览器上下文中,前一个网页(与当前页面不一定同域)unload 的时间戳,如果无前一个网页 unload ,则与 fetchStart 值相等
navigationStart: 1441112691935,
// 前一个网页(与当前页面同域)unload 的时间戳,如果无前一个网页 unload 或者前一个网页与当前页面不同域,则值为 0
unloadEventStart: 0,
unloadEventEnd: 0,
// 第一个 HTTP 重定向发生时的时间。有跳转且是同域名内的重定向才算,否则值为 0
redirectStart: 0,
redirectEnd: 0,
…
// 开始解析渲染 DOM 树的时间,此时 Document.readyState 变为 loading,并将抛出 readystatechange 相关事件
domLoading: 1441112692690,
…
var timing = performance.timing;
var loadingTime = timing .domLoading - timing.navigationStart;//开始
渲染时间
看一下navigator timing浏览器支持情况
对于IE等低版本浏览器是不行的。
IE8 等低版本浏览器 通过 cookie 记录时间戳的方式来统计,需要注意的是 Cookie 方式只能统计到站内跳转的数据。首次进入没有好的统计方法。
头部资源加载时间: