在当今世界,性能确实至关重要。 开发人员需要能够准确地评估其软件的性能。 对于那些在网上工作的人,W3C具有全新的API ,可以可靠地节省时间。 该API是“ 高分辨率时间API” 。 本文将探讨高分辨率时间API,并展示如何使用它。
为了衡量函数的性能,Web开发人员曾经使用过JavaScript Date.now()
方法。 通常,时间保持代码类似于以下内容:
var startTime = Date.now();
// A time consuming function
foo();
var test1 = Date.now();
// Another time consuming function
bar();
var test2 = Date.now();
// Print results
console.debug("Test1 time: " + (test1 - startTime));
console.debug("Test2 time: " + (test2 - test1));
Date.now()
方法根据系统时间检索当前时间戳。 不幸的是,它的精度在用户代理之间有所不同,因此不是很可靠。 为了缓解此问题,W3C对High Time Time API进行了标准化。 该API被描述为“ 一个JavaScript接口,它以毫秒级的分辨率提供当前时间,因此不会受到系统时钟偏差或调整的影响
。” 10月23日RD 2012,该规范成为W3C提议的推荐-成为一个建议之前的最后一步。 ( 更新 12月17 日 )在12月17 日它们成为W3C推荐标准
高分辨率时间API的工作方式
我必须承认,这是我读过的最简单的API,因为它仅包含一个方法。 该API扩展了Performance
接口, Navigation Timing API也使用该接口 。 如果您从未听说过,请查看Navigation Timing API:如何有效分析页面负载 。
公开的唯一方法是now()
,该方法返回一个DOMHighResTimeStamp
,以毫秒为单位表示当前时间。 时间戳非常精确,精确到千分之一毫秒。 请注意,虽然Date.now()
返回自1970年1月1日00:00:00 UTC,经过的毫秒数performance.now()
返回的毫秒数,用微秒小数部分,从performance.timing.navigationStart()
,即开始导航到performance.now()
调用的文档。 Date.now()
和performance.now()
之间的另一个重要区别是后者是单调递增的,因此两次调用之间的区别永远不会为负。
也许您想知道高分辨率时间API将如何更改您的代码。 好消息是它不会改变任何东西。 您所需要做的就是将Date.now()
与performance.now()
以提高测量的准确性。 考虑到这一点,以前的代码将被重写,如下所示。
var startTime = performance.now();
// A time consuming function
foo();
var test1 = performance.now();
// Another time consuming function
bar();
var test2 = performance.now();
// Print more accurate results
console.debug("Test1 time: " + (test1 - startTime));
console.debug("Test2 time: " + (test2 - test1));
兼容性
当前,很少有浏览器支持高分辨率时间API。 唯一支持该API的台式机浏览器是Internet Explorer 10,不带前缀的Firefox 15+,以及带有“ webkit”前缀( performance.webkitNow()
)的版本20以上的Chrome 。 Chrome似乎将从版本24开始使用非前缀版本 。 在撰写本文时,没有移动浏览器支持此API。
由于支持范围不广,因此您首先需要的功能是测试浏览器支持以及是否带有前缀。 如果浏览器使用API的未前缀版本,则以下函数将返回空字符串。 如果使用带前缀的版本,则返回该前缀。 如果不支持该API,则返回null
。
function getPrefix() {
var prefix = null;
if (window.performance !== undefined) {
if (window.performance.now !== undefined)
prefix = "";
else {
var browserPrefixes = ["webkit","moz","ms","o"];
// Test all vendor prefixes
for(var i = 0; i < browserPrefixes.length; i++) {
if (window.performance[browserPrefixes[i] + "Now"] != undefined) {
prefix = browserPrefixes[i];
break;
}
}
}
}
return prefix;
}
对于不支持API的浏览器,可以使用垫片。
垫片的作者Tony Gentilcore是API的贡献者之一。
Gentilcore在他的标题为“ JavaScript的更好计时器 ” 的文章中,编写了代码,该代码首先搜索本机支持,并使用Date.getTime()
方法作为后备。 代码如下所示。
window.performance = window.performance || {};
performance.now = (function() {
return performance.now ||
performance.mozNow ||
performance.msNow ||
performance.oNow ||
performance.webkitNow ||
function() { return new Date().getTime(); };
})();
全部放在一起
本节将指导您完成一个简单的演示页面。 该演示将首先测试对浏览器的支持,然后使用一个名为doBenchmark
的函数,该函数依靠两个虚拟函数来使用performance.now()
方法进行基准测试。 请注意,我介绍了与API不相关的getTime()
函数。 其唯一目的是避免无用的重复,并使代码更整洁。 该演示的源代码如下所示。
<!DOCTYPE html>
<html>
<head>
<title>High Resolution Time API Test Page</title>
<script>
function foo() {
for(var i = 0; i < 10000000; i++);
}
function bar() {
for(var i = 0; i < 100000000; i++);
}
function getPrefix() {
var prefix = null;
if (window.performance !== undefined) {
if (window.performance.now !== undefined)
prefix = "";
else {
var browserPrefixes = ["webkit","moz","ms","o"];
// Test all vendor prefixes
for(var i = 0; i < browserPrefixes.length; i++) {
if (window.performance[browserPrefixes[i] + "Now"] != undefined) {
prefix = browserPrefixes[i];
break;
}
}
}
}
return prefix;
}
function getTime() {
return (prefix === "") ? window.performance.now() : window.performance[prefix + "Now"]();
}
function doBenchmark() {
if (prefix === null)
document.getElementById("log").innerHTML = "Your browser does not support High Resolution Time API";
else {
var startTime = getTime();
foo();
var test1 = getTime();
bar();
var test2 = getTime();
document.getElementById("log").innerHTML += "Test1 time: " + (test1 - startTime) + "<br />";
document.getElementById("log").innerHTML += "Test2 time: " + (test2 - test1) + "<br />";
}
}
var prefix = getPrefix();
window.onload = doBenchmark;
</script>
</head>
<body>
<p id="log"></p>
</body>
</html>
结论
在本文中,我展示了什么是高分辨率时间API,以及如何使用它。 正如我提到的那样,它尚未得到广泛支持,因此要准确测试Web应用程序,您还需要等待一段时间。 但是,如您所见,该API非常简单,因为它包含一个方法。 因此,一旦浏览器支持得到改善,迁移到高分辨率时间将变得轻松快捷。
From: https://www.sitepoint.com/discovering-the-high-resolution-time-api/