AICon 深圳站聚焦 Agent 技术、应用与生态,大咖分享实战干货 了解详情
写点什么

使用 HMTL5 API 监控前端性能

  • 2015-10-13
  • 本文字数:3363 字

    阅读完需:约 11 分钟

用户计时 API

用户计时 API 可以在网页应用中测量两个预定义标记之间的性能。开发者仅仅需要分别定义测量的开始和结束标记。可以通过 JavaScript 对象“ performance ”提供的函数,对计时位置进行标记。

var measuring_start = performance.now();通过“ now ”函数,可以在网页应用的获取计时用高精度时间戳。和该函数类似的是Date 对象,它同样可以获取当前时间戳。二者的主要区别是时间精度,now 函数的返回值的w3c 文档中明确要求,必须能够表示精确到千分位小数的毫秒值。另外now 函数返回的数值,是从浏览器的“浏览开始事件(navigationStart)”开始到现在的毫秒数。

复制代码
performance.now()
35438640.775000006
(new Date()).getTime()
1443063066478

如果希望分析一个图片的加载性能,可以在图片的加载(load)事件中设置第二个标记。图片加载的耗时,就是“measure_start”和“measure_end”两个变量之间的差值(单位毫秒)。

复制代码
<html>
<head>
<meta charset="utf-8" />
<title>test timing</title>
</head>
<body>
<img src="http://cdn3.infoqstatic.com/statics_s2_20150922
-0305u1/styles/i/logo_bigger.jpg" alt="image" >
<script type="text/javascript">
var measure_start = performance.now();
document.getElementsByTagName("img")[0].addEventListener
("load", function() {
var measure_end = performance.now();
console.log("image load time: " + (measure_end - measure_start) + "ms");
}, false);
</script>
</body>
</html>

访问这个 html 之后,可以在控制台看见输出:

image load time: 24.395ms同时,可以和 Chrome 开发者工具中网络标签页的加载时间做比较:

(点击放大图像)

除了使用now 函数直接获取时间戳之外,Performance 接口还提供了标记(mark)函数。开发者可以在任何需要记录时间的地方创建、清除标记。

复制代码
performance.mark("start");
performance.mark("end");

mark 函数不返回任何值,但是后续可以通过标记的名称来获取标记的数据。如果要计算标记之间的差值,可以通过“measure”函数来完成。该函数需要三个参数,第一个参数定义了该差值的名称,第二个和第三个变量指定标记的名称。同样,该函数也不返回任何值。

performance.measure("difference", "start", "end");上面这个例子,计算了“start”和“end”两个标记之间的差值,并将差值命名为“difference”。需要特别注意的是,这里相同的名称都会被记录,不会覆盖。

前面说到了,mark、measure 这两个函数,不会返回任何值。如果要读取标记或者测量的内容,需要通过调用 Performance 接口中的“getEntries”、“getEntriesByType”或者“getEntriesByName”函数读取。其中“getEntries”返回当前performance 对象中保存的所有标记(包括网页加载的资源)和测量结果;“getEntriesByType”函数通过类型获取对应的标记;“getEntriesByName”函数通过标记(或者测量结果)名称来获取对应的数据。这些函数的返回值是 PerformanceEntry 对象列表,包含名称、开始时间、耗时等字段。

例如,如果要获取所有的标记或者测量结果,可以通过“getEntriesByType”函数获取:

复制代码
performance.mark("start");
performance.mark("end");
performance.measure("difference", "start", "end");
var marks = performance.getEntriesByType("mark");
var measures = performance.getEntriesByType("measure");
console.log("===marks===:")
marks.forEach(function(mark) {
console.log(mark.name + ": " + mark.startTime);
})
console.log("===measures===:")
measures.forEach(function(measure){
console.log(measure.name + ": " + measure.duration)
})

在浏览器(Chrome)控制台执行后的输出为:

复制代码
===marks===:
start: 6805479.590000001
end: 6805479.74
===measures===:
difference: 0.14999999944120646

可以看见,返回的对象中,name 字段为设置的标记(测量结果)的名称,对于标记可以通过 startTime 获取标记时间(和前文提到的 now 函数一样,这里返回的时间也是相对于 navigationStart 事件),对于计算结果,可以通过 duration 字段获取计算结果。上面示例中使用的“mark”、“measure”两种类型之外,浏览器(Chrome、Firefox 等)已经支持“resource”类型。也就是说,这些浏览器已经默认帮我们测量了所有外部资源加载的耗时。对于之前示例中的 html(包含一个图片的引用),如果在浏览器的控制台执行下面的 js 代码,可以直接看见这个图片加载的耗时:

复制代码
performance.getEntriesByType("resource").forEach(function(r) {
console.log(r.name + ": " + r.duration)
})

上述代码输出(Chrome)为:

复制代码
http://cdn3.infoqstatic.com/statics_s2_20150922-
0305u1/styles/i/logo_bigger.jpg: 21.696999901905656

这个数据和 Chrome 开发者工具中网络标签页中对该请求记录的耗时完全一致。

如果要直接通过标记、测量结果名称获取数据,可以通过 getEntriesByName 函数获取。需要注意的是,该函数同样返回的是 PerformanceEntry 对象数组,需要迭代获取具体数据。

同样,Performance 接口也提供了移除标记的接口。可以通过 clearMarks 和 clearMeasures 函数,删除之前创建的标记和测量结果。这两个函数都接收一个可选的名称参数,如果传入名称,则删除指定名称的数据,否则清空标记 / 测量结果。

复制代码
performance.clearMarks();
performance.mark("start");
performance.mark("end");
var marks = performance.getEntriesByType("mark");
console.log("before clear:")
marks.forEach(function(mark) {
console.log(mark.name + ": " + mark.startTime);
})
performance.clearMarks("start");
marks = performance.getEntriesByType("mark");
console.log("after clear:")
marks.forEach(function(mark) {
console.log(mark.name + ": " + mark.startTime);
})

上述代码执行后的输出为:

复制代码
before clear:
start: 9080690.565000001
end: 9080690.575000001
after clear:
end: 9080690.575000001

也就是说,执行了performance.clearMarks("start");之后,“start”标记被清除了。

浏览计时 API

浏览计时 API 统计了一个网页从卸载当前文档开始到加载完毕这整个流程中,每个节点的时间戳。和用户计时API 不同的是,浏览器计时API 的时间,是标准的时间戳。每个节点的时间戳,都保存在 performance.timing对象中。其中包含的每个节点,可以参考下图:

(点击放大图像)

复制代码
console.log(performance.timing.domLoading);
console.log(performance.timing.domComplete);
console.log("load time: " + (performance.timing.domComplete -
performance.timing.domLoading ));

例如,可以通过获取 domComplete(DOM 构建完成)和 domLoading(DOM 开始构建)的差值,来计算构建 DOM 树消耗的时间。

除了 timing 对象中保存的各个节点加载时间戳,performance 对象中还保存了和 navigation 对象。它保存了当前页面的加载类型和重定向次数。其中,加载类型类型有:

  • TYPE_NAVIGATE(type == 0):通过点击链接、输入地址、表单提交、脚本初开启等方式加载
  • TYPE_RELOAD(type == 1):通过重新加载或者 location.reload() 操作加载
  • TYPE_BACK_FORWARD(type == 2):通过浏览器历史遍历操作加载
  • TYPE_RESERVED(type == 255):上面没有定义的其他方式

如直接打开一个页面,在控制台中执行:

console.log(performance.navigation.type);上述脚本执行后,控制台会输出 0,表示这是直接打开的一个页面。再次刷新页面,重新执行上面的 JavaScript 片段,则会输出 1,表示这是一次重新加载。

performance.timing.redirectCount 记录了当前页面经历的重定向次数。

浏览器支持

用户计时 API 已经大部分浏览器支持,如IE10+、Chrome 25+、Firefox 15+ 等,但是Safari 等浏览器还不支持。对于浏览计时API,更多的浏览器已经支持,包括Chrome、Firefox、IE9+、Safari 8+ 等等。


感谢徐川对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

2015-10-13 18:2410019

评论

发布
暂无评论
发现更多内容

Databend x CubeFS:面向未来的企业级云原生数据存储与分析

Databend

金融科技领袖汇聚:图技术+大模型驱动金融创新

悦数图数据库

图数据库

视频教程:如何集成Perforce Helix Core与S3 存储,助力无限扩展储存空间

龙智—DevSecOps解决方案

版本控制 S3 版本控制软件 储存库

59 人参会,探讨新年发展!龙蜥社区技术委员会、运营委员会会议圆满结束

OpenAnolis小助手

开源 操作系统 国产操作系统 龙蜥社区

龙蜥系统运维联盟第二次会议圆满召开,深度探讨联盟发展方向

OpenAnolis小助手

开源 操作系统 国产操作系统 龙蜥社区

脑洞大开丨让 AI 写代码,能做出什么样的项目?

阿里巴巴云原生

阿里云 云原生

免费!API对接淘宝店铺啦!—操作超简易!

技术冰糖葫芦

API 接口

玄湾OS 重磅开源!专为容器安全运行的轻量级云原生操作系统

OpenCloudOS

Linux

详解CloudBees CI,助力Jenkins用户顺利迁移并构建高效CI/CD平台

龙智—DevSecOps解决方案

ci 持续集成 CD

走进 Intel,深度探讨合作发展规划交流会圆满结束 | 理事长走进系列

OpenAnolis小助手

开源 操作系统 国产操作系统 龙蜥社区

悦数图数据库推出 AI 知识图谱构建器及图语言生成助手

悦数图数据库

Kubernetes与低代码开发应用:实现高效协同开发的新模式

不在线第一只蜗牛

Kubernetes 容器 低代码

ai制图软件有哪些?这5款自动生成绘画工具值得推荐!

彭宏豪95

人工智能 在线白板 办公软件 AIGC AI绘画

软件测试学习笔记丨Allure2 添加用例分类

测试人

软件测试

Git进阶命令-reset

不在线第一只蜗牛

提升质量透明度,动力电池企业的数据驱动生产实践 | 数据要素 × 工业制造

奇点云

奇点云 数据要素 工业制造

龙蜥社区荣获 2023 年度龙芯“十佳基础软件合作伙伴”奖

OpenAnolis小助手

开源 操作系统 国产操作系统 龙蜥社区

谈谈我对 AIGC 趋势下软件工程重塑的理解

阿里巴巴云原生

阿里云 云原生 AIGC

龙蜥社区第 22 次运营委员会圆满结束!

OpenAnolis小助手

开源 操作系统 国产操作系统 龙蜥社区

Redis 又双叒叕改开源协议了,微软提前推出高性能替代方案 Garnet

小猿姐

redis microsoft 开源协议

龙年新目标!龙蜥安全联盟第三次月会圆满结束

OpenAnolis小助手

开源 操作系统 国产操作系统 龙蜥社区

龙蜥操作系统荣登开放原子开源基金会“2023 生态开源项目”奖项榜单

OpenAnolis小助手

开源 操作系统 国产操作系统 龙蜥社区

使用HMTL5 API监控前端性能_HTML5_金灵杰_InfoQ精选文章