分页面、区域、浏览器、性能指标php
页面的性能指标详解:css
白屏时间(first Paint Time)——用户从打开页面开始到页面开始有东西呈现为止html
首屏时间——用户浏览器首屏内全部内容都呈现出来所花费的时间前端
用户可操做时间(dom Interactive)——用户能够进行正常的点击、输入等操做,默承认以统计domready时间,由于一般会在这时候绑定事件操做html5
总下载时间——页面全部资源都加载完成并呈现出来所花的时间,即页面 onload 的时间java
肯定统计起点:jquery
咱们须要在用户输入 URL 或者点击连接的时候就开始统计,由于这样才能衡量用户的等待时间。高端浏览器Navigation Timing接口;普通浏览器经过 cookie 记录时间戳的方式来统计,须要注意的是 Cookie 方式只能统计到站内跳转的数据。git
公式:github
白屏时间=开始渲染时间(首字节时间+HTML下载完成时间)+头部资源加载时间web
如何获取:
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)*1000复制代码
其余浏览器:
大部分浏览器没有特定函数,必须想其余办法来监测。仔细观察 WebPagetest 视图分析发现,白屏时间出如今头部外链资源加载完附近,由于浏览器只有加载并解析完头部资源才会真正渲染页面。基于此咱们能够经过获取头部资源加载完的时刻来近似统计白屏时间。尽管并不精确,但却考虑了影响白屏的主要因素:首字节时间和头部资源加载时间(HTML下载完成时间很是微小)。
有一个点:mod_36ad799.js等几个js为何会在hm.js以前下载?html代码以下
这貌似与咱们熟知的脚本阻塞解析不符啊,理应是脚本插入hm.js在先,致使DOM树改变,从新绘制DOM树,而后继续往下解析……缘由是如今的浏览器对这个过程作了优化:
web的模式是同步的,开发者但愿解析到一个script标签时当即解析执行脚本,并阻塞文档的解析直到脚本执行完。若是脚本是外引的,则网络必须先请求到这个资源——这个过程也是同步的,会阻塞文档的解析直到资源被请求到。这个模式保持了不少年,而且在html4及html5中都特别指定了。开发者能够将脚本标识为defer,以使其不阻塞文档解析,并在文档解析结束后执行。Html5增长了标记脚本为异步的选项,以使脚本的解析执行使用另外一个线程。
Webkit和Firefox都作了这个优化,当执行脚本时,另外一个线程解析剩下的文档,并加载后面须要经过网络加载的资源。这种方式可使资源并行加载从而使总体速度更快。须要注意的是,预解析并不改变Dom树,它将这个工做留给主解析过程,本身只解析外部资源的引用,好比外部脚本、样式表及图片。
样式表采用另外一种不一样的模式。理论上,既然样式表不改变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 方式只能统计到站内跳转的数据。 首次进入没有好的统计方法。
头部资源加载时间:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8"/>
<script>
var start_time = +new Date; //测试时间起点,实际统计起点为 DNS 查询
</script>
<!-- 3s 后这个 js 才会返回 -->
<script src="script.php"></script>
<script>
var end_time = +new Date; //时间终点
var headtime = end_time - start_time; //头部资源加载时间
console.log(headtime);
</script>
</head>
<body>
<p>在头部资源加载完以前页面将是白屏</p>
<p>script.php 被模拟设置 3s 后返回,head 底部内嵌 JS 等待前面 js 返回后才执行</p>
<p>script.php 替换成一个执行长时间循环的 js 效果也同样</p>
</body>
</html>复制代码
这个比较简单,在head的前面计时开始,在head最末尾计时结束,中间的差值就计算为头部资源加载时间。
因此,最终计算方法:
var firstPaintTime = end_time - performance.timing.navigationStart复制代码
首屏时间的统计比较复杂,由于涉及图片等多种元素及异步渲染等方式。观察加载视图可发现,影响首屏的主要因素的图片的加载。经过统计首屏内图片的加载时间即可以获取首屏渲染完成的时间。统计流程以下:
首屏位置调用 API 开始统计 -> 绑定首屏内全部图片的 load 事件 -> 页面加载完后判断图片是否在首屏内,找出加载最慢的一张 -> 首屏时间
这是同步加载状况下的简单统计逻辑,另外须要注意的几点:
//IE gif重复onload解决
var img=new Image();
img.load=function(){
//do something
img.load=null;//从新赋值为null
}
img.src='××.gif';复制代码
统计方法1:
原理:在首屏渲染以前埋上处理逻辑,使用定时器不断的去检测img节点的图片。判断图片是否在首屏和加载完成,找到首屏中加载时间最慢的的图片完成的时间,从而计算出首屏时间。若是首屏有没有图片,若是没图片就用domready时间。
缺点: 1.浏览器定时器最大精度为55ms 2.背景图片加载没有计算在内 3.不断检测并执行的脚本耗时
统计方法2:
原理:对于网页高度小于屏幕的网站来讲,只要在页面底部加上脚本打印当前时间便可;或者对于网页高度大于一屏的网页来讲,只要在估算接近于一屏幕的元素的位置后,打印一下当前时间。固然这个时间要得把首屏中全部图片的加载时间也算上。
缺点: 1.须要每一个页面手动加入到对应位置 2.背景图片加载没有计算在内
用户可操做为全部DOM都解析完毕的时间,默承认以统计domready时间,由于一般会在这时候绑定事件操做。对于使用了模块化异步加载的 JS 能够在代码中去主动标记重要 JS 的加载时间,这也是产品指标的统计方式。
使用jquery中的$(document).ready()便是此意义 window.performance.timing.domInteractive window.performance.timing.domContentLoadedEventStart
计算公式:
performance.timing.domInteractive - performance.timing.navigationStart复制代码
默承认以统计onload时间,这样能够统计同步加载的资源所有加载完的耗时。若是页面中存在不少异步渲染,能够将异步渲染所有完成的时间做为总下载时间。
计算公式:
performance.timing.loadEventStart- performance.timing.navigationStart复制代码
片断摘自:美团性能分析框架和性能监控平台,并加入部分其余文字
对于统计脚本,须要知足两个条件:
肯定了数据统计脚本的约束条件以后,咱们从哪里获得这些数据呢?目前使用的主要途径有:
对于主文档加载速度,咱们从宏观到微观的作了这样的分解,从上到下的时间流,右边的时刻标记了每一个指标从哪里开始计算到哪里截止,好比,跳转时间 redirect
由 redirectEnd - redirectStart
计算获得,其余的类推:
采集主文档加载速度的具体作法是:
对于静态资源的加载速度,咱们也作了相似的分解和采集(使用resource timing API):
须要特别提示的是,若是你使用 CDN 的话,须要让 CDN 服务商加上 Timing-Allow-Origin 的响应头,才能拿到静态资源的数据。
而对于主文档生成速度,咱们则开发了性能统计的 Library,在框架级别集成后端性能的时间指标。
该API规范所定义的JavaScript接口可以提供精确到微秒级的当前时间,而且不会受到系统时钟误差或调整的影响。对于性能分析来讲,精确的测量结果意义重大。
var perf = performance.now();
// console output 439985.4570000316复制代码
经过这一规范,网站开发者可以以编程方式肯定页面的当前可见状态,从而使网站可以更有效地利用电源与CPU。
当页面得到或失去焦点时,文档对象的visibilitychange事件便会被触发。
document.addEventListener('visibilitychange', function(event){if(document.hidden){// Page currently hidden.}else{// Page currently visible.}});复制代码
这一事件对于了解页面的可见状态十分有用,举例来讲,用户可能会同时打开多个浏览器标签,而你但愿只在用户显示你的网站页面时才进行某些操做(好比播放一段音频文件、或是执行一段JavaScript动画),就能够经过这一事件进行触发。对于移动设备来讲,若是用户在某个标签中打开了你的网站,但正在另外一个标签中浏览其它内容时,这一特性可以节省该设备的电池消耗。(虽然对于你的网站性能来讲意义不大……)复制代码
浏览器支持
下表列举了当前主流浏览器对性能API的支持,其中标注星号的内容并不是来自于Web性能工做小组。
规范 | Internet Explorer | Firefox | Chrome | Safari | Opera | iOS Safari | Android |
Navigation Timing | 9 | 31 | 所有 | 8 | 26 | 8 (不包括 8.1) | 4.1 |
High Resolution Timing | 10 | 31 | 所有 | 8 | 26 | 8 (不包括 8.1) | 4.4 |
Page Visibility | 10 | 31 | 所有 | 7 | 26 | 7.1 | 4.4 |
Resource Timing | 10 | 34 | 所有 | - | 26 | - | 4.4 |
Battery Status* | - | 31 (部分支持) | 38 | - | 26 | - | - |
User Timing | 10 | - | 所有 | - | 26 | - | 4.4 |
Beacon | - | 31 | 39 | - | 26 | - | - |
Animation Timing | 10 | 31 | 所有 | 6.1 | 26 | 7.1 | 4.4 |
Resource Hints | - | - | 仅限Canary版 | - | - | - | - |
Frame Timing | - | - | - | - | - | - | - |
Navigation Error Logging | - | - | - | - | - | - | - |
WebP* | - | - | 所有 | - | 26 | - | 4.1 |
Picture element and srcset attribute * | - | - | 38 | - | 26 | - | - |
其它
DZone.com在《Performance & Monitoring 2015》这份白皮书中专门介绍了性能API以及W3C所推荐的新协议、标准及HTML元素,并提供了简单的示例。能够在这里下载完整的白皮书(须要注册)。本文中的示例代码即来自于该白皮书。
若是想了解有关Web性能API的更多内容,能够参考W3C官方文档或这篇博客。
1.使用测试工具自测和优化(工具如ySlow/,线上工具www.webpagetest.org、阿里测、gtmetrix)
ySlow/ShowSlow:http://www.showslow.com/ 【前端性能监控系统,前端性能指标数据展现,没法实现自动化监控用户真实的应用场景,针对移动端的性能监控,目前因为其自己依赖的工具绝大多数只有PC端,在移动端缺少相应的数据上报工具(特别是移动端自己复杂的网络环境),因此若是想使用ShowSlow做为前端性能监控平台,须要单独实现数据收集系统,而只是将ShowSlow看成展现系统使用,开源】
Page Speed: 【基于一系列优化规则对网站进行检测,相似的有Yslow(推荐使用https://gtmetrix.com/来检测网站性能和规则,使用不一样的工具检测对比) 】
阿里测:基于WebPageTest,网页前端性能测试工具;
PhantomJS:自动化监测,模拟Phantom JS 是一个服务器端的 JavaScript API 的 WebKit,基于它能够轻松实现 web 自动化测试。相似的有berserkJS。可是都是服务器模拟测试,不能监控用户真实环境。
webpagetest线上版
基于WebPagetest的阿里测(已下线,不举例了,上17测:http://www.17ce.com/)
综合了pagespeed和ySlow的GTmetrix
2.启用线上监控用户真实状况(前端性能监控平台)
看几个例子
透视宝:http://www.toushibao.com/brower.html 【前端性能上报,图表展现,监控用户真实的应用场景,付费】
提供了每个请求的详细信息
能够按选择的字段排序,经过过滤进行相似数据对比,能够查看每个请求的详细信息,不过按url搜索貌似没有用,若是这个有用的话那就能够对同一个页面作时间的对比。
优势:
1.柱状时间线排列
2.多个指标同时展现,便于比较
缺点:
1.缺乏部分关键时间(白屏时间=首字节时间+HTML下载完成时间+头部资源加载时间)
2.性能没有按地区分类,参考价值大大减小
3.免费版本只存储3天
Browser Insight:http://www.oneapm.com/bi/feature.html 【前端性能上报,图表展现,监控用户真实的应用场景,付费】
要查看某次访问的详情须要在云快照中拍照,模拟访问
优势:
1.指标齐全
2.慢加载追踪全部资源加载状况
缺点:
1.四个性能指标没有按地区分类的数据,参考价值大大减小
mmtrix(性能魔方):http://www.mmtrix.com/
先看评测
http://www.7k7k.com WEB评测实例:统计数据不错
真实用户性能监控:
优势:
1.支持不一样地域的四个关键性能指标的展现
2.支持展现不一样区间的数据比例
缺点:
1.不支持https协议
还有一个国内较大的性能监控平台听云
指标比价少,没有太多价值。就不作比较了。
看一下国外的性能监控网站
先看newrelic(rpm.newrelic.com),注册须要本身使用外网代理
和OneAPM很像,前端性能指标不全。用来监控ajax请求, js报错等还不错,可是知足不了个人需求。
appdynamics(www.appdynamics.com)
注册竟然找不到中国
随便选了一个canmroon
和透视宝很像。免费版本保存时间更少,只有24小时。
总的来讲,mmtrix和OneAPM指标更全一些。尚未研究他们的监控代码,不知道监控的指标正确与否。公司的性能这块也刚起步,离优秀还有很大一段距离,就写到这里了,但愿对研究性能刚起步的童鞋有点做用,任务还很重,加油。