写点什么

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

评论

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

玩转 LLMs 之「为什么不问问 Milvus」

Zilliz

Milvus 向量数据库 autogpt zillizcloud langchain

视频后期特效处理软件:Motion 5 最新中文激活版

真大的脸盆

Mac Mac 软件 视频特效合成 视频特效工具 特效合成

内部开发者平台|自建还是购买,企业应如何选择?

SEAL安全

平台工程 企业号 5 月 PK 榜 内部开发平台

大模型总是「胡说八道」怎么办?手把手教你如何应对!

Zilliz

Milvus 向量数据库 ChatGPT zillizcloud langchain

PoseiSwap IDO在Bounce上启动在即,如何参与?

股市老人

如何使用Go实现代理模式

Jack

golang 设计模式

低代码平台中的分布式RPC框架(约3000行代码)

canonical

开源 dubbo RPC框架

WorkPlus AI助理 | 将企业业务场景与ChatGPT结合

BeeWorks

苹果Mac视频转码编辑工具Compressor v4.6.4最新中文激活版

Rose

下载 fcpx Compressor Mac下载 苹果视频编码工具 Compressor破解版

Ableton Live Suite 11破解版下载 音乐制作软件

Rose

音乐制作 Ableton Live 11中文版 Live Suite 11破解 Ableton Live Suite下载

名侦探白洞(一):智能家居灵异事件

脑极体

AI 智能家居

C语言编程—判断语句

芯动大师

基于 Log 的通用增量 Checkpoint 在美团的进展

Apache Flink

大数据 flink 实时计算

PoseiSwap IDO在Bounce上启动在即,如何参与?

鳄鱼视界

SpringBoot + Docker 实现一次构建到处运行

Java你猿哥

Java Docker Spring Boot ssm 容器化部署

常用的表格检测识别方法——表格结构识别方法(上)

合合技术团队

人工智能 深度学习 算法 人工智能文字识别 表格检测

有哪些好用的企业即时通讯软件值得推荐?

BeeWorks

CloudQuery v2.0.0 发布 新增数据保护、数据变更、连接管理等功能

BinTools图尔兹

数据库 国产数据库 版本发布

2023-05-23:如果交换字符串 X 中的两个不同位置的字母,使得它和字符串 Y 相等, 那么称 X 和 Y 两个字符串相似。如果这两个字符串本身是相等的,那它们也是相似的。 例如,“tars“

福大大架构师每日一题

golang 算法 rust 福大大

fastposter v2.15.0 从繁琐到简单,简洁好用的海报生成器

物有本末

FastApi Pillow 海报生成器 海报编辑器 海报小程序

什么是 Final Cut Pro? fcpx视频剪辑下载安装

Rose

Final Cut Pro下载 Final Cut Pro破解版 FCPX软件 fcpx Mac视频剪辑软件

耕升 GeForce RTX 4060 Ti 系列,为玩家带来DLSS3+1080P光追游戏体验!

极客天地

升级正当时,高性价比的影驰 GeForce RTX™ 4060 Ti 8G开箱评测

极客天地

PoseiSwap IDO在Bounce上启动在即,如何参与?

西柚子

Mac视频后期特效工具 motion5 v5.6.4进行了额外修复和优化

Rose

mac软件下载 Motion 5 motion5中文 视频后期特效处理 Motion 5破解版

Django笔记三十五之admin后台界面介绍

Hunter熊

Python django admin

Logic Pro X(苹果专业音频制作软件)v10.7.8中文版

Rose

苹果mac软件下载 Logic Pro X下载 Logic Pro X破解 Logic Pro X教程 音频制作软件

2023年,Flutter3.10版本的变化有哪些?

没有用户名丶

小程序容器

以敏捷性为目标,构建良好企业生态

智达方通

数据驱动 数据孤岛 智达方通 全面预算管理 数据分析系统

1.5万字+30张图盘点程序员面试必会MySQL索引常见的11个知识点

Java你猿哥

Java MySQL 数据 ssm 索引

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