发现用户计时API

几个月前, 我讲了一些HTML5 API ,这些API部分地侧重于如何衡量性能。 一种技术是通过高分辨率时间API,这是我上一篇文章中描述的API。 该API允许您以毫秒级的分辨率来检索当前时间,而不受系统时钟偏差或调整的影响,这又使我们能够准确地测量JavaScript代码的性能。 尽管此API很有用,但使我们免于在代码中引入大量变量的痛苦。 另外,如果要测量在多个文件或模块中分割的代码的性能,则必须引入全局变量。 为了解决这些问题,我们可以使用用户计时API。

什么是用户计时API

User Timing API被定义为一个接口,可帮助Web开发人员通过访问高精度时间戳来评估其应用程序的性能。 换句话说,该API使您可以准确地测量和报告JavaScript代码的性能,这在需要对代码进行基准测试时非常理想。 作为 该API是W3C建议。 因此,规格是稳定的,几乎没有变化。

该API涉及两个主要概念:标记和度量。 第一个实现PerformanceMark接口,第二个实现PerformanceMeasure接口。 这两个接口都扩展了PerformanceEntry接口 。 标记表示瞬间(时间戳),而小节表示两个标记之间经过的时间。 因为它们都扩展了PerformanceEntry接口,所以它们拥有相同的四个只读属性:

  • name :与标记或小节相关的助记符名称,用于检索它。
  • entryType :指定对象的类型,即它是标记还是小节。
  • startTime :如果对象是标记,则这是DOMHighResTimeStamp ,这是使用高分辨率时间API的performance.now()方法检索的高精度时间戳。 如果对象是DOMHighResTimeStamp ,则它包含DOMHighResTimeStamp开始标记的DOMHighResTimeStamp
  • duration :如果对象是Mark,则该值始终为0(零)。 如果对象是小节,则它包含两个标记之间经过的时间。

该用户计时API公开了四个属于window.performance对象的方法。 他们是:

  • mark(name) :存储具有关联名称的DOMHighResTimeStamp
  • clearMarks([name]) :删除一个或所有存储的标记。
  • measure(name[, mark1[, mark2]]) :存储使用提供的名称的两个Mark之间经过的时间。
  • clearMeasures([name]) :删除一个或所有已存储的度量。

请注意,传递给mark()measure()函数的名称不是唯一的ID。 您可以根据需要多次使用相同的名称。 在这种情况下,当您执行名称检索时,将返回按startTime属性排序的数组。

在继续之前,让我们看一个简单的示例,该示例采用了所描述的一些方法。 假设我们要测量一个函数的执行时间,然后删除该测量而不显示数据。 执行此任务的代码如下所示:

performance.mark("startFoo");
// A time consuming function
foo();
performance.mark("endFoo");

performance.measure("durationFoo", "startFoo", "endFoo");

// Delete all Marks
performance.clearMarks();
// Delete the Measure "durationFoo"
performance.clearMeasure("durationFoo");

此代码段显示了如何调用前面介绍的所有方法。 但是,存储时间戳然后在不使用度量​​的情况下将其删除是完全没有用的。 要检索标记和度量的数据,我们需要使用属于Performance接口的其他两种方法: getEntriesByType(type)getEntriesByName(name) 。 前者返回由type参数指定的type的实体列表(即Marks的“ mark”)。 后者返回名称由name参数指定的实体的列表。 它们都返回基于startTime属性排序的列表。

浏览器支持

在桌面和移动浏览器上,对该API的支持都不错。 此外,那些确实支持此API的应用程序不使用供应商前缀。 实现了用户计时API的台式机和移动浏览器是Internet Explorer 10 +,Chrome 25+和Opera 15+。 但是,由于Firefox在W3C推荐过程中的当前阶段,我们可以期望Firefox很快支持它。

“好的,但是如果我想在不支持该API的浏览器中使用该API怎么办?”

很高兴你问! 对我们来说幸运的是,有一个名为usertiming.js的polyfill允许我们使用前面描述的方法。 坏消息是此polyfill仅在支持High Time Time API及其performance.now()方法的浏览器中起作用。

演示版

本部分提供了一个简单的演示,使您可以尝试本文中介绍的概念。 该演示定义了一个具有两个输入字段的简单表格。 在它们内部,我们有两个数字将用于模拟给定持续时间的耗时函数。 如果用户的浏览器不支持API,我们还将测试浏览器是否支持并显示“不支持API”消息。 如果浏览器支持User Timing API,我们将在表单内按钮的click事件上附加一个侦听器。 单击后,我们将运行两个模拟函数并存储时间戳。 然后,我们测量经过的时间并显示一些存储的信息。 此处提供以下代码的实时演示。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <meta name="author" content="Aurelio De Rosa">
    <title>User Timing API Demo by Aurelio De Rosa</title>
    <style>
      body
      {
        max-width: 500px;
        margin: 2em auto;
        font-size: 20px;
      }

      h1
      {
        text-align: center;
      }

      .hidden
      {
        display: none;
      }

      .field-wrapper
      {
        margin-bottom: 1em;
      }

      .button-demo
      {
        padding: 0.5em;
        display: block;
        margin: 1em auto;
      }

      .author
      {
        display: block;
        margin-top: 1em;
      }
    </style>
  </head>
  <body>
    <h1>User Timing API</h1>
    <form>
      <div class="field-wrapper">
        <label for="count-ut-1">Test 1: Count until</label>
        <input type="number" id="count-ut-1" value="100000" />
      </div>

      <div class="field-wrapper">
        <label for="count-ut-2">Test 2: Count until</label>
        <input type="number" id="count-ut-2" value="1000000" />
      </div>

      <button type="button" id="button-play-ut" class="button-demo">Run demo</button>
    </form>
    <span id="ut-unsupported" class="hidden">API not supported</span>
    <div id="ut-results" class="hidden">
      <h2>Marks</h2>
      <div id="ut-marks"></div>
      <h2>Measures</h2>
      <div id="ut-measures"></div>
    </div>

    <small class="author">
      Demo created by <a href="http://www.audero.it">Aurelio De Rosa</a>
      (<a href="https://twitter.com/AurelioDeRosa">@AurelioDeRosa</a>)
    </small>

    <script>
      window.performance = window.performance || {};
      if (performance.mark === undefined) {
        document.getElementById('ut-unsupported').classList.remove('hidden');
        document.getElementById('button-play-ut').setAttribute('disabled', 'disabled');
      } else {
        document.getElementById('button-play-ut').addEventListener('click', function() {
          var i;
          var perfMarks;
          var perfMeasures;

          document.getElementById('ut-results').classList.remove('hidden');
          // A time consuming function
          performance.mark("startTime1");
          for(i = 0; i < parseInt(document.getElementById('count-ut-1').value); i++);
            performance.mark("endTime1")

            // Another time consuming function
            performance.mark("startTime2");
            for(i = 0; i < parseInt(document.getElementById('count-ut-2').value); i++);
              performance.mark("endTime2");
              performance.measure("durationTime1", "startTime1", "endTime1");
              performance.measure("durationTime2", "startTime2", "endTime2");
              performance.measure("durationTimeTotal", "startTime1", "endTime2");

              // Print marks
              perfMarks = performance.getEntriesByType("mark");
              document.getElementById('ut-marks').innerHTML = '';
              for (i = 0; i < perfMarks.length; i++) {
                document.getElementById('ut-marks').innerHTML +=
                  "Name: " + perfMarks[i].name + " - " +
                  "Start Time: " + perfMarks[i].startTime + "<br />";
              }

              // Print measures
              perfMeasures = performance.getEntriesByType("measure");
              document.getElementById('ut-measures').innerHTML = '';
              for (i = 0; i < perfMeasures.length; i++) {
                document.getElementById('ut-measures').innerHTML +=
                  "Name: " + perfMeasures[i].name + " - " +
                  "Duration: " + perfMeasures[i].duration + "<br />";
              }
              performance.clearMarks();
              performance.clearMeasures();
        });
      }
    </script>
  </body>
</html>

结论

本文探讨了User Timing API,并展示了它如何帮助您测试JavaScript代码的性能。 性能真的很重要,我们应该争取一点点的改进。

该API不会引入太多概念,因此您应该不难理解其属性和方法。 此外,它在浏览器中的支持非常好,因此您可以立即可靠地使用它。 但是,对于不支持User Timing API的用户(最著名的是Firefox),可以使用polyfill。

From: https://www.sitepoint.com/discovering-user-timing-api/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值