探针支持对性能指标进行自定义设置,包括完全加载、白屏、首屏、可交互,可以利用浏览器原生接口或探针接口方式。
利用浏览器接口performance.mark(…),需加入ty_
前缀表示是TINGYUN的指标,调用接口的时间点将会被探针记录为指标触发时间。
设置白屏:
performance.mark('ty_fp');
设置首屏:
performance.mark('ty_fs');
设置可交互:
performance.mark('ty_dr');
设置完全加载时间:
performance.mark('ty_le');
如果设置时间晚于load事件触发,需要在探针配置中设置指标的等待时间,如果此时没有mark其中的指标,探针将等待一段时间上传,最终等待时间取所有未设置指标的最大值。
示例:
pfDelay: {
fs: 1000,
le: 2000
}
如果load时le
和 fs
都没有设置,探针将等待2秒。
当浏览器版本过低,不支持performance.now接口时,可以使用探针定义时间API。IE 9浏览器环境下,iframe内嵌页面无法计算白屏、首屏,且浏览器无法获取慢页面元素,对于指标计算问题,建议使用程序打点方案,来获取相对准确的指标时间。
首先需要在探针之前放置一段额外JS代码:
window["__TINGYUN"]={data:{},config:{},mark:function(markName,optionalData){var splits=markName.split("_");var prefix=splits[0];var performanceName=splits[1];if(prefix==="ty"&&performanceName){this.data[performanceName]={timestamp:+new Date,data:optionalData}}},getData:function(){return this.data}};
此段代码会提供一个 __TINGYUN
对象,使用其中提供设置时间的接口,当探针使用异步方式加载时,此方式保证接口可用。
window['__TINGYUN'].mark(markName[, optionalData])
参数 | 含义 | 是否必须 | 说明 |
---|---|---|---|
markName | 打点的指标 | 是 | 名称以ty_开头,后面为具体替换的指标名称。 |
optionalData | 自定义数据 | 否 | 预留参数, 一些自定义数据。 |
调用示例:
if(window['__TINGYUN']) window['__TINGYUN'].mark('ty_fp'); // 自定义白屏时间, 调用的时间点即为白屏时间
if(window['__TINGYUN']) window['__TINGYUN'].mark('ty_fs'); // 自定义首屏时间, 调用的时间点即为首屏时间
if(window['__TINGYUN']) window['__TINGYUN'].mark('ty_dr'); // 自定义可交互时间, 调用的时间点即为可交互时间
if(window['__TINGYUN']) window['__TINGYUN'].mark('ty_le'); // 自定义完全加载时间, 调用的时间点即为完全加载时间
window['__TINGYUN'].getData()
返回示例:
{
le: {
timestamp: 1557739276477,
data: null
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- 探针嵌码开始 -->
<!--此部分代码需要在混合嵌码中随探针一起嵌入, 在探针之前, 本段代码在生产中会被压缩,下方展示的示例源码-->
<script>
window['__TINGYUN'] = {
// 打点数据
data: {
},
// 探针外置配置
config: {
},
mark: function(markName, optionalData) {
var splits = markName.split('_');
var prefix = splits[0];
var performanceName = splits[1];
if(prefix === 'ty' && performanceName) {
this.data[performanceName] = {
timestamp: +new Date,
data: optionalData
};
}
},
getData: function() {
return this.data;
}
};
</script>
<!--原本的探针嵌码-->
<script defer src="tingyun.js"></script>
<!-- 探针嵌码结束 -->
</head>
<body>
</body>
</html>
__TINGYUN 对象描述:
字段 | 意义 | 说明 |
---|---|---|
data | 自定义打点的数据存储对象。 | |
config | 探针配置外置变量。 | 有些配置不方便直接修改探针文件,可以放着这个对象中,对象中的内容优先获取。 |
mark | 打点接口。 | |
config | 查看已打点数据接口。 |
白屏指标,IE9 中可以使用performance.timing.msFirstPaint
方式获取, 但iframe 嵌套页面无法获取,且此值的初始化时间没有明确定义, 在页面 load
事件发生后尝试获取,依然可能获取到 0 值, 所以,为了准确设置白屏,建议打点。
白屏打点位置建议为head部分尾部, 此时head中阻塞资源JS,css已加载完毕,主要cssom已构建,浏览器可以继续构建DOM树,并开始渲染页面,可以作为白屏时间估计点。
<head>
<!-- browser 探针嵌码开始 -->
<script>
// 预定义代码
</script>
<script defer src="tingyun.js"></script>
<!-- browser 探针嵌码结束 -->
<script>
if(window['__TINGYUN']) window['__TINGYUN'].mark('ty_fp');
</script>
</head>-->
<body>
<script ></script>
</body>
如果对于具体嵌码页面有更准确的白屏时间点,可以自行更改位置。
探针对于首屏的计算基于白屏(大于等于白屏), 之后通过浏览器接口获取首屏线上的图片资源计算,但IE9首先不能准确获取白屏时间,又没有接口提供,所以无法计算准确首屏,建议手动打点。
打点位置建议在关键图片加载完毕,或页面中iframe加载完毕时。
示例1:
<body>
<!-- ... -->
<img src="xxxx" onload="markFs()">
<!-- ... -->
<script>
function markFs() {
if(window['__TINGYUN']) window['__TINGYUN'].mark('ty_fs');
}
</script>
<body>
示例2:
<body>
<!-- ... -->
<iframe src="xxxx" onload="markFs()">
<!-- ... -->
<script>
function markFs() {
if(window['__TINGYUN']) window['__TINGYUN'].mark('ty_fs');
}
</script>
<body>
探针监控 DOMContentLoaded
事件作为可交互时间, 但对于异步加载,渲染的页面或骨架屏页面,此事件触发时,虽然浏览器可以呈现并可以交互,但 很可能内容没有加载,没有元素可以交互,所以对于此类页面,如果要获取更准确的可交互时间,建议手动打点。
探针获取performance.timing.loadEventEnd
时间点作为完全加载时间,但对于异步加载,渲染的页面或骨架屏页面,此事件触发时,可能关键组件并没有 加载渲染完毕, 对于此类页面,建议打点获取更准确的完全加载时间。
对于完全加载(可交互, 参数为ty_dr)打点示例: 假设页面有3个关键组件部分,不能确定加载顺序,可以在3个组件加载完毕的回调中打点:
// 组件1加载完成
function component1Loaded() {
if(window['__TINGYUN']) window['__TINGYUN'].mark('ty_le');
}
// 组件2加载完成
function component2Loaded() {
if(window['__TINGYUN']) window['__TINGYUN'].mark('ty_le');
}
// 组件3加载完成
function component3Loaded() {
if(window['__TINGYUN']) window['__TINGYUN'].mark('ty_le');
}
上述方式,完全加载会使用最后一个组件加载时间。
按照目前的方案,自定义打点后,需要延迟页面数据上传时间(页面上传时间原本在页面触发load
事件时),探针配置中需要加入对应的估计延时时间,可以在探针预定义对象中的config
属性中配置。
示例:
<script>
window['__TINGYUN'] = {
...(省略代码)
// 探针外置配置
config: {
pfDelay: {
dr: 2000 // 对于可交互打点,load事件后等待2秒后计算并上传页面数据
}
}
...(省略代码)
};
</script>