JavaScript等:4种创新的方法来衡量浏览器中的时间

本文的作者(我们今天将其翻译发表)决定讨论几种不同的在浏览器中测量时间的方法。要使用它们,您将需要访问Web开发中使用的各种API,因此它们不适用于Node.js平台。的确,如果有人需要用一种不寻常的方式来测量Node.js中的时间,那么我们相信,在阅读了这些材料之后,他可能对此主题有一些想法。



在Web Worker(而不是Service Worker)中使用无限同步循环


由于Web Worker本质上是在Web浏览器中运行的线程,因此它们可以运行无穷循环,而不会冒阻塞主线程的风险。这使您可以处理一段时间,其持续时间少于一毫秒。这种准确性尤其适用于工人需要做出高度时间依赖性的决策的情况。这些决定的采用可以(以很高的准确性)报告给主流。例如,当自某个事件以来经过的微秒数用质数表示时,您可以派生出一些东西。为了使时间精度达到微秒,您可以使用performance.now方法

▍优势


  1. 可以达到的精度,以微秒为单位。
  2. .
  3. , , . - .
  4. . , setInterval, terminate , . MDN : « terminate() Worker . , ».


  1. 即使使用此方法可以以小于一毫秒的时间间隔工作,向主线程发送消息也是异步的。即,不可能在主线程中以与工人决定需要执行这些动作相同的精度执行某些动作。
  2. 此方法会完全加载流,这可能导致手机上的电池消耗增加。
  3. 此方法需要网络工作者的支持。
  4. 如果与它关联的选项卡处于非活动状态,Web Worker中的无限循环不会暂停。

实施例上Codesandbox

使用CSS动画处理与时间相关的事件(尤其是-animationiteration)


此方法涉及创建具有无限动画的元素。在这里您可以尝试使用element div,但是我必须说,如该方法缺点列表的第2段所述,div最好不要将元素用于这些目的。因此,如果我们的元素具有无限的动画效果,则可以订阅其事件animationiteration并在间隔到期的那一刻接收通知animation-duration

▍优势


  1. 如果浏览器选项卡不活动,则自动暂停。在这种情况下,根本不会发生我们感兴趣的事件。因此,您不必担心解决处理选项卡处于非活动状态然后被激活的时间所累积的许多事件的问题。
  2. div DOM. , React-, , . div .
  3. , , . — :

    .addEventListener("animationiteration", fun).
  4. animation-delay.


  1. . , , .
  2. 对DOM和CSSOM的依赖。其他CSS规则可能会影响描述动画的那些规则。因此,我建议您为计时器的组织创建一种随机命名的先前不存在的标记,例如<just-a-timer-element></<just-a-timer-element>也许-是否值得创建一个自定义元素,在其中清晰地隐藏CSS动画代码?(实际上,所有这些都是有争议的想法)。
  3. 如果元素具有样式,则此方法无效display: none;
  4. 不准确 根据我的测试,倒计时的精度约为1毫秒。您可以找到一个示例来尝试确切地了解它的工作原理,下面提供了一个链接。

实施例上Codesandbox

使用svg标记(SMIL动画)


看一下以下SVG元素:

<svg>
  <rect>
    <animate
      attributeName="rx"
      values="0;1"
      dur="1s"
      repeatCount="indefinite"
    />
  </rect>
</svg>

如果使用以下代码:,animate.addEventListener('repeat', fun)则该函数fun将每秒调用一次dur就我们而言,每秒。

▍优势


  1. 即使将样式分配给SVG元素,此方法也有效display: none;
  2. 从DOM中删除SVG元素后,倒数计时将自动停止。
  3. 页面完全加载后,事件生成才会开始。
  4. 如果选项卡变为非活动状态,则“计时器”将自动暂停。

▍缺点


  1. 与使用CSS动画计算时间间隔的情况一样,其他程序员似乎无法理解此方法的应用。
  2. 对DOM和CSSOM的依赖。也就是说-在这里,我们具有与CSS动画计数时间方法相同的不良功能。即-由于其他CSS规则而导致“计时器”中断的可能性。
  3. IE和Edge不支持它(直到浏览器从Microsoft转移到Chromium)。
  4. 不准确 根据我的测试,这种计时器与最准确的方法的偏差可能非常令人印象深刻,为15毫秒。您可以通过实验示例来验证自己,下面提供了链接。
  5. 直到页面完全加载后,倒计时才会开始。的确,在某些情况下,此方法的“减号”可能变成“加号”。

实施例上Codesandbox

使用Web动画API


Web Animations API允许您使用JavaScript代码为DOM元素设置动画。

有趣的是,您甚至可以为未安装的元素设置动画!这使您可以访问纯JavaScript(和Web API)中可用的时间机制。

这是一个替代实现setTimeout

function ownSetTimeout(callback, duration) {
  const div = document.createElement('div');

  const keyframes = new KeyframeEffect(div, [], { duration, iterations: 1 });

  const animation = new Animation(
    keyframes,
    document.timeline
  );

  animation.play();

  animation.addEventListener('finish', () => {
    callback();
  });
}

整齐吧?

▍优势


  1. 一个不需要与DOM交互的独立解决方案。
  2. 不熟悉这种方法的程序员将很容易理解相应代码的含义。
  3. “计时器”在非活动标签上暂停。

▍缺点


  1. Web Animations API-该技术仍处于试验阶段。不要在生产中使用它。
  2. 浏览器支持非常差。此方法可能仅在Chromium中有效。
  3. 尽管具有该解决方案的所有优点,但对于某些人来说,它似乎还是很不直观的。
  4. 如果将“计时器”暂停在不活动的选项卡上,则可以用此解决方案来代替setTimeout
  5. 此方法不能用于计算间隔。程序员只能使用一个事件onfinish
  6. 准确性低。根据我的实验,误差很容易达到±5毫秒。

→  实施例上Codesandbox

奖金


为了节省时间,您可以使用Web Audio API。这是间隔和延迟准确地工作的另一种好方法。这是一篇很棒的文章。

摘要


我了解,我在这里列出的与时间打交道的技术可以使所有人受益匪浅。但我就是忍不住写这篇文章,是因为我一直认为,setTimeoutsetInterval-这些都是与一定的时间间隔异步工作的唯一途径。但是实际上,事实证明,这还远远没有。谁知道,也许某个人在某个项目上工作时必须面对一些不寻常的限制,但在某些特殊条件下,这里强调的工作方法可能会随着时间的推移而变得有用。

亲爱的读者们!在什么情况下,您认为此处介绍的基于时间的方法会派上用场?


All Articles