写点什么

使用 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:2410139

评论

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

顶尖认证!Cloud Ace 培训师荣膺 Google Cloud 两项重量级培训师大奖

Cloud Ace 云一

云计算 谷歌云 谷歌云培训

Cloud Ace 荣获 2025 年 Google Cloud 大中华区年度国家合作伙伴大奖!

Cloud Ace 云一

Google Cloud 谷歌云 企业云服务 Google Cloud Next'25

刚学吉他的人怎么跟谱练习 如何用Guitar Pro软件深入了解乐谱

阿拉灯神丁

吉他学习 吉他谱 Guitar Pro Guitar Pro8 Mac乐谱制作软件

从零到一开发 DeepSeek 智能聊天机器人

AI时代的一滴水

Python Chat AI API DeepSeek

观测云多步拨测最佳实践

观测云

可用性监测

新报告显示西班牙俱乐部在本土青训球员留用方面处于领先地位

新消费日报

镜舟科技亮相 2025 中国移动云智算大会,展示数据湖仓一体创新方案

镜舟科技

人工智能 数据库 数据架构 中国移动 镜舟科技

2025年全球最富裕城市

财见

高性能虚拟环境存储解决方案:基于 Xinnor RAID 引擎和 Kioxia PCIe 5.0 驱动器

Sergey Platonov

测试 HPC Performance raid Kiokia

外贸企业怎么选网络专线? SD-WAN五大优势助力企业出海!

Ogcloud

SD-WAN 企业组网 SD-WAN组网 sd-wan专线 SD-WAN厂家

金仓数据库KingbaseES单机扩集群部署方案介绍

金仓技术

数据库· 电科金仓 金仓数据库

MSKE铭文,一次正确的选择,足以改变你一生命运!

MSKE铭文

比特币行情 MSKE铭文 马斯克铭文 比特币铭文

2025年智能合约玩法创新白皮书:九大核心模块与收益模型重构Web3经济范式

区块链软件开发推广运营

交易所开发 dapp开发 链游开发 公链开发 代币开发

高并发秒杀系统设计:关键技术解析与典型陷阱规避

飞算JavaAI开发助手

AI应用突围,中小企业的新周期已至

新消费日报

企业跨地域多分支组网难?SD-WAN轻松解决!

Ogcloud

SD-WAN SD-WAN组网 SD-WAN厂商 sd-wan专线 SD-WAN厂家

Corinex获投资实现规模扩张

财见

a16z 最新报告:AI 数字人应用层即将爆发,或将孕育数十亿美金市场丨 Voice Agent 学习笔记

声网

面试官:如果某个业务量突然提升100倍QPS你会怎么做?

不在线第一只蜗牛

程序员 面试

深入研究:京东图片搜索商品API详解

tbapi

京东API 京东拍立淘API 京东图片搜索API 京东图片API

2025上海国际电子元器件展览会

AIOTE智博会

Lalamove基于Flink实时湖仓演进之路

Apache Flink

大数据 flink 实时计算

商汤「日日新 V6」发布,国内最强多模态推理;三星新款「球球」机器人将接入 Gemini AI丨日报

声网

IBM收购 Hakkoda Inc.,扩展数据专业能力以推动客户的AI转型

财见

后端程序员逆袭之路:巧用 AI 工具,拿下高薪 offer

飞算JavaAI开发助手

JVM实战—线上FGC的几种案例

量贩潮汐·WholesaleTide

JVM

DeepSeek大模型Prompt工程深度实践(开发者空间Notebook版)

华为云开发者联盟

昇腾 DeepSeek 华为开发者空间

从 Greenplum 到 StarRocks:头部金融客户如何通过架构升级实现“实时分析自由”?

镜舟科技

数据架构 金融 分析型数据库 StarRocks 实时分析

全球移动货币业务取得突破

财见

HR Path扩大爱尔兰英国业务版图

财见

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