首屏渲染时间获取 performance.now()
Performance — 前端性能监控利器
最近在写一个监控脚本,终于有机会接触到了这一块,整理后写下了本文。
Performance是一个做前端性能监控离不开的API,最好在页面完全加载完成之后再使用,因为很多值必须在页面完全加载之后才能得到。最简单的办法是在window.onload事件中读取各种数据。
属性
timing (PerformanceTiming)
从输入url到用户可以使用页面的全过程时间统计,会返回一个PerformanceTiming对象,单位均为毫秒
按触发顺序排列所有属性:(更详细标准的解释请参看:W3C Editor's Draft)navigationStart
:在同一个浏览器上下文中,前一个网页(与当前页面不一定同域)unload 的时间戳,如果无前一个网页 unload ,则与 fetchStart 值相等unloadEventStart
:前一个网页(与当前页面同域)unload 的时间戳,如果无前一个网页 unload 或者前一个网页与当前页面不同域,则值为 0unloadEventEnd
:和 unloadEventStart 相对应,返回前一个网页 unload 事件绑定的回调函数执行完毕的时间戳redirectStart
:第一个 HTTP 重定向发生时的时间。有跳转且是同域名内的重定向才算,否则值为 0redirectEnd
:最后一个 HTTP 重定向完成时的时间。有跳转且是同域名内的重定向才算,否则值为 0fetchStart
:浏览器准备好使用 HTTP 请求抓取文档的时间,这发生在检查本地缓存之前domainLookupStart
:DNS 域名查询开始的时间,如果使用了本地缓存(即无 DNS 查询)或持久连接,则与 fetchStart 值相等domainLookupEnd
:DNS 域名查询完成的时间,如果使用了本地缓存(即无 DNS 查询)或持久连接,则与 fetchStart 值相等connectStart
:HTTP(TCP) 开始建立连接的时间,如果是持久连接,则与 fetchStart 值相等,如果在传输层发生了错误且重新建立连接,则这里显示的是新建立的连接开始的时间connectEnd
:HTTP(TCP) 完成建立连接的时间(完成握手),如果是持久连接,则与 fetchStart 值相等,如果在传输层发生了错误且重新建立连接,则这里显示的是新建立的连接完成的时间
注意:这里握手结束,包括安全连接建立完成、SOCKS 授权通过
secureConnectionStart
:HTTPS 连接开始的时间,如果不是安全连接,则值为 0requestStart
:HTTP 请求读取真实文档开始的时间(完成建立连接),包括从本地读取缓存,连接错误重连时,这里显示的也是新建立连接的时间responseStart
:HTTP 开始接收响应的时间(获取到第一个字节),包括从本地读取缓存responseEnd
:HTTP 响应全部接收完成的时间(获取到最后一个字节),包括从本地读取缓存domLoading
:开始解析渲染 DOM 树的时间,此时 Document.readyState 变为 loading,并将抛出 readystatechange 相关事件domInteractive
:完成解析 DOM 树的时间,Document.readyState 变为 interactive,并将抛出 readystatechange 相关事件
注意:只是 DOM 树解析完成,这时候并没有开始加载网页内的资源
domContentLoadedEventStart
:DOM 解析完成后,网页内资源加载开始的时间,文档发生 DOMContentLoaded事件的时间domContentLoadedEventEnd
:DOM 解析完成后,网页内资源加载完成的时间(如 JS 脚本加载执行完毕),文档的DOMContentLoaded 事件的结束时间domComplete
:DOM 树解析完成,且资源也准备就绪的时间,Document.readyState 变为 complete,并将抛出 readystatechange 相关事件loadEventStart
:load 事件发送给文档,也即 load 回调函数开始执行的时间,如果没有绑定 load 事件,值为 0loadEventEnd
:load 事件的回调函数执行完毕的时间,如果没有绑定 load 事件,值为 0
常用计算:
DNS查询耗时 :domainLookupEnd - domainLookupStart
TCP链接耗时 :connectEnd - connectStart
request请求耗时 :responseEnd - responseStart
解析dom树耗时 : domComplete - domInteractive
白屏时间 :responseStart - navigationStart
domready时间(用户可操作时间节点) :domContentLoadedEventEnd - navigationStart
onload时间(总下载时间) :loadEventEnd - navigationStart
navigation
旨在告诉开发者当前页面是通过什么方式导航过来的,只有两个属性:type
,redirectCount
type:标志页面导航类型,值如下表
type常数 | 枚举值 | 描述 |
---|---|---|
TYPE_NAVIGATE | 0 | 普通进入,包括:点击链接、在地址栏中输入 URL、表单提交、或者通过除下表中 TYPE_RELOAD 和 TYPE_BACK_FORWARD 的方式初始化脚本。 |
TYPE_RELOAD | 1 | 通过刷新进入,包括:浏览器的刷新按钮、快捷键刷新、location.reload()等方法。 |
TYPE_BACK_FORWARD | 2 | 通过操作历史记录进入,包括:浏览器的前进后退按钮、快捷键操作、history.forward()、history.back()、history.go(num)。 |
TYPE_UNDEFINED | 255 | 其他非以上类型的方式进入。 |
注意:稍带个小知识,history.go(url)这种非标准写法目前主流浏览器均不支持,问题可参考http://stackoverflow.com/questions/6277283/history-gourl-issue
redirectCount:表示到达最终页面前,重定向的次数,但是这个接口有同源策略限制,即仅能检测同源的重定向。
注意:所有前端模拟的重定向都无法统计到,因为不属于HTTP重定向
memory
描述内存多少,是在Chrome中添加的一个非标准属性。jsHeapSizeLimit
: 内存大小限制totalJSHeapSize
: 可使用的内存usedJSHeapSize
: JS对象(包括V8引擎内部对象)占用的内存,不能大于totalJSHeapSize,如果大于,有可能出现了内存泄漏
方法
getEntries()
获取所有资源请求的时间数据,这个函数返回一个按startTime排序的对象数组,数组成员除了会自动根据所请求资源的变化而改变以外,还可以用mark(),measure()方法自定义添加,该对象的属性中除了包含资源加载时间还有以下五个属性。name
:资源名称,是资源的绝对路径或调用mark方法自定义的名称startTime
:开始时间duration
:加载时间entryType
:资源类型,entryType类型不同数组中的对象结构也不同!具体见下initiatorType
:谁发起的请求,具体见下
entryType的值:
值 | 该类型对象 | 描述 |
---|---|---|
mark | PerformanceMark | 通过mark()方法添加到数组中的对象 |
measure | PerformanceMeasure | 通过measure()方法添加到数组中的对象 |
resource | PerformanceResourceTiming | 所有资源加载时间,用处最多 |
navigation | PerformanceNavigationTiming | 现除chrome和Opera外均不支持,导航相关信息 |
frame | PerformanceFrameTiming | 现浏览器均未支持 |
server | PerformanceServerTiming | 未查到相关资料 |
initiatorType的值:
发起对象 | 值 | 描述 |
---|---|---|
a Element | link /script /img /iframe 等 |
通过标签形式加载的资源,值是该节点名的小写形式 |
a CSS resourc | css |
通过css样式加载的资源,比如background的url方式加载资源 |
a XMLHttpRequest object | xmlhttprequest |
通过xhr加载的资源 |
a PerformanceNavigationTiming object | navigation |
当对象是PerformanceNavigationTiming时返回 |
//根据entryType类型返回的不同对象
PerformanceMark:{ //通过mark()方法添加的对象
entryType:"mark"
name:调用mark()方法时自定义的名字
startTime: 做标记的时间
duration:0
}
PerformanceMeasure:{ //通过measure()方法添加的对象
entryType:"measure"
name:调用measure()方法时自定义的名字
startTime: 开始量的时间
duration:标记的两个量的时间间隔
}
PerformanceResourceTiming:{ //可以用来做一个精准的进度条
entryType:"resource"
name:资源的绝对路径,即URL
startTime: 即将抓取资源的时间,
duration: responseEnd - startTime
initiatorType:略!/:傲娇脸
//其他属性请参考performance.timing
}
PerformanceNavigationTiming:{
entryType:"navigation"
name:本页路由,即地址栏看到的地址
startTime: 0
duration: loadEventEnd - startTime
initiatorType:"navigation"
//其他属性请参考performance.timing
}
请注意:
- 目前通过
<audio>
,<video>
加载资源,initiatorType还无法返回"audio"和"video",chrome中只能返回空字符串,firfox返回"other" - 如果一个图片在页面内既用img引入,又作为背景图片引入,那么initiatorType返回的"img"
- performance.getEntries(params)这种形式仍出于草案阶段,目前所有浏览器均为支持。但是非常有用,期待早些实现。
- 使用该方法统计资源信息的时候首先可以合理利用clearResourceTimings清除已统计过的对象避免重复统计,其次要过滤掉因上报统计数据而产生的对象。
getEntriesByName(name,type[optional]),getEntriesByType(type)
name
:想要筛选出的资源名type
:entryType的值中一个
返回值仍是一个数组,这个数组相当于getEntries()方法经过所填参数筛选后的一个子集
clearResourceTimings();
该方法无参数无返回值,可以清楚目前所有entryType为"resource"的数据,用于写单页应用的统计脚本非常有用
mark(name),measure(name, startMark, endMark),clearMarks(),clearMeasures()
用于做标记和清除标记,供用户自定义统计一些数据,比如某函数运行耗时等
name
:自定义的名称,不要和getEntries()返回的数组中其他name重复startMark
:作为开始时间的标记名称或PerformanceTiming的一个属性endMark
:作为结束时间的标记名称或PerformanceTiming的一个属性
创建标记:mark(name);
记录两个标记的时间间隔:measure(name, startMark, endMark);
清除指定标记:window.performance.clearMarks(name);
清除所有标记:window.performance.clearMarks();
清除指定记录间隔数据:window.performance.clearMeasures(name);
清除所有记录间隔数据:window.performance.clearMeasures();
now()
performance.now()是当前时间与performance.timing.navigationStart的时间差,以微秒(百万分之一秒)为单位的时间,与 Date.now()-performance.timing.navigationStart的区别是不受系统程序执行阻塞的影响,因此更加精准。
友情提示
目前主流浏览器虽然都已支持Performance对象,但是并不能支持它上面的全部属性和方法,本文主要依据chrome编写,因此提到的chrome浏览器都是兼容的,其他具体使用时兼容性请自行测试,目前已测如下:
1.safari浏览器(包括mac和ios)只支持navigation,timing,now其余均不支持
2.微信浏览器支持timing,navigation属性,不支持performance.getEntries方法
推荐及参考文章
MDN-Performance
W3C Editor's Draft
初探performance-监控网页与程序性能
使用性能API快速分析web前端性能
首屏渲染时间获取 performance.now()的更多相关文章
- 如何使用webpack优化首屏渲染时间
其实说到性能优化,他的范围太广了,今天我们就只聊一聊通过webpack配置减少http请求数量这个点吧. 简单说下工作中遇到的问题吧,我们做的一个项目中首页用了十多张图片,每张图片都是一个静态资源,所 ...
- 腾讯优测优分享 | 探索react native首屏渲染最佳实践
腾讯优测是专业的移动云测试平台,旗下的优分享不定时提供大量移动研发及测试相关的干货~ 此文主要与以下内容相关,希望对大家有帮助. react native给了我们使用javascript开发原生app ...
- 探索react native首屏渲染最佳实践
文 / 腾讯 龚麒 0.前言 react native给了我们使用javascript开发原生app的能力,在使用react native完成兴趣部落安卓端发现tab改造后,我们开始对由react n ...
- vue 首屏渲染优化 -- 这个不错
这篇文章分享了从遇到前端业务性能问题,到分析.解决并且梳理出通用的Vue 2.x 组件级懒加载解决方案(Vue Lazy Component )的过程. 初始加载资源过多 问题起源于我们的一个页面,下 ...
- 前端性能优化——首屏时间&&白屏时间
1.首屏时间概念 首屏时间是指用户打开一个网站时,直到浏览器首页面内容渲染完成的时间. 2.白屏时间概念 白屏时间即是,浏览器开始显示内容的时间,所以我们一般认为解析完<head>的时刻, ...
- 基于 SSR 的预渲染首屏直出方案
基于 SSR 的预渲染首屏直出方案 Create React Doc 是一个使用 React 的 markdown 文档站点生成工具.此前在 Create React Doc 中引入了预渲染技术来预先 ...
- 从解析HTML开始,破解页面渲染时间长难题
摘要:在本文中,将重点关注网页的初始渲染,即它从解析 HTML 开始. 我将探索可能导致高渲染时间的问题,以及如何解决它们. 本文分享自华为云社区<页面首屏渲染性能指南>,作者:Ocean ...
- react 首屏性能优化
首屏优化点:1.加载包(bundle.js)文件的大小,越小,首屏渲染速度越快 (按需加载) 2.优先渲染用户直观看到的页面部分(懒加载) 技术点:react-loadable . react-laz ...
- H5性能测试,首屏时间统计(Argus)
Argus 腾讯质量开发平台,官网链接:https://wetest.qq.com/product/argus 主要针对性:H5的游戏性能测试 主要介绍: 独家首屏时间统计: 告别人工掐秒 自动统计首 ...
随机推荐
- Centos6.5 (或Linux) 安装Elasticsearch
一.可以在网上下载对饮的版本:https://github.com/elastic/elasticsearch,本次安装的是5.5.3. 首先保证虚拟机上安装了jdk,jdk的版本只是是1.7或以上 ...
- HOJ 2091 Chess(三维简单DP)
Chess My Tags (Edit) Source : Univ. of Alberta Local Contest 1999.10.16 Time limit : 1 sec Memory li ...
- JAVA补充-接口
1.接口详解 package com.neusoft.interfaced; /** * 接口: * 语法:interface 接口名{ * public static final 变量1=值1: * ...
- 【转】JavaScript中的匿名函数及函数的闭包
对闭包理解一直不甚明了,在此特转摘博文一篇以备查用. 原文地址:http://www.cnblogs.com/rainman/archive/2009/05/04/1448899.html 相关文章: ...
- SQL Fundamentals || DCL(Data Control Language) || 角色ROLES
SQL Fundamentals || Oracle SQL语言 语句 解释 Create user Creates a user(usually performed by a DBA) Grant ...
- postgreSQL 自增需要使用序列
postgreSQL 自增需要使用序列 1.使用SERIAL CREATE TABLE users ( id SERIAL4 primary key , name character varying, ...
- Assign the task---hdu3974(线段树优化+dfs)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3974 题意就是:公司有n个员工,关系有n-1个,T x y 代表把工作y交给员工x: 员工可以把工作交 ...
- c字符检测函数
isalpha(c) /*判断是否为英文字符*/iscntrl(c) /*判断是否为控制字符*/ isdigit(c) /*判断是否为阿拉伯数字0到9*/isgraph(c) ...
- [py]requests+json模块处理api数据,flask前台展示
需要处理接口json数据,过滤字段,处理字段等. 一大波json数据来了 参考: https://stedolan.github.io/jq/tutorial/ https://api.github. ...
- EXTJS 4.2.1.883 Summary 合计栏宽度bug
EXTJS 4.2.1.883中改进了summary插件,使合计栏能够在grid最底部显示,但是列宽和表格对不上,解决方法: 找到以下样式 .x-docked-summary .x-grid-tabl ...