JavaScript y más: 4 enfoques creativos para medir el tiempo en los navegadores

El autor del artículo, cuya traducción publicamos hoy, decidió hablar sobre varias formas inusuales de medir el tiempo en los navegadores. Para usarlos, necesitará acceso a varias API que se usan en el desarrollo web, por lo que no son adecuadas para la plataforma Node.js. Es cierto que si alguien necesita una forma inusual de medir el tiempo en Node.js, entonces, creemos que, después de leer este material, puede tener algunas ideas sobre este tema.



Usar un bucle sincrónico infinito en un trabajador web (no en un trabajador de servicio)


Dado que los trabajadores web son esencialmente hilos que se ejecutan en un navegador web, pueden ejecutar bucles sin fin sin correr el riesgo de bloquear el hilo principal. Esto le permite trabajar con períodos de tiempo, cuya duración es inferior a un milisegundo. Esta precisión es especialmente adecuada para aquellos casos en que un trabajador necesita tomar decisiones que dependen mucho del tiempo. La adopción de estas decisiones se puede informar (con un nivel de precisión muy alto) a la transmisión principal. Por ejemplo, puede derivar algo en el caso cuando el número de microsegundos que han pasado desde un determinado evento está representado por un número primo. Para trabajar con una precisión de microsegundos a lo largo del tiempo, puede usar el método performance.now .

▍Ventajas


  1. Precisión alcanzable expresada en microsegundos.
  2. .
  3. , , . - .
  4. . , setInterval, terminate , . MDN : « terminate() Worker . , ».


  1. Aunque este método hace posible trabajar con intervalos de tiempo inferiores a un milisegundo, el envío de mensajes al subproceso principal funciona de forma asincrónica. Es decir, es imposible realizar ciertas acciones en la secuencia principal con la misma precisión con la que se toma la decisión en el trabajador de que estas acciones deben realizarse.
  2. Este método carga completamente la transmisión, lo que puede conducir a un mayor consumo de batería en los teléfonos.
  3. Este método requiere el apoyo de los trabajadores web.
  4. Un bucle infinito en un trabajador web no se detiene si la pestaña asociada está inactiva.

Ejemplo en Codesandbox

Uso de animaciones CSS para eventos relacionados con el tiempo (en particular, animación)


Este método implica crear un elemento con animación sin fin. Aquí puede intentar usar el elemento div, pero debo decir que, como se señaló en el párrafo 2 de la lista de deficiencias de este método, dives mejor no usar elementos para estos fines. Entonces, si tenemos un elemento con animación sin fin, podemos suscribirnos a su evento animationiterationy recibir notificaciones en los momentos en que expire el intervalo animation-duration.

▍Ventajas


  1. Pausa automáticamente si la pestaña del navegador se vuelve inactiva. En este caso, el evento de interés para nosotros simplemente no ocurre. Por lo tanto, no necesita preocuparse por resolver el problema de procesar muchos eventos que se han acumulado durante el tiempo en que la pestaña estaba inactiva y luego activada.
  2. div DOM. , React-, , . div .
  3. , , . — :

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


  1. . , , .
  2. Dependencia de DOM y CSSOM. Otras reglas CSS pueden afectar a las que describen la animación. Por lo tanto, le aconsejo que cree para la organización del temporizador un tipo de etiqueta previamente inexistente llamada aleatoriamente <just-a-timer-element></<just-a-timer-element>. Tal vez, ¿vale la pena crear un elemento personalizado, dentro del cual el código de animación CSS esté perfectamente oculto? (todas estas son ideas bastante controvertidas, en realidad).
  3. Este método no funciona si el elemento tiene un estilo display: none;.
  4. Inexactitud. De acuerdo con mis pruebas, la precisión de la cuenta regresiva puede ser de aproximadamente 1 ms. Usted, para averiguar exactamente cómo funciona para usted, puede experimentar con un ejemplo, un enlace al que se proporciona a continuación.

Ejemplo en Codesandbox

Usando la etiqueta svg (animaciones SMIL)


Eche un vistazo al siguiente elemento SVG:

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

Si usa el siguiente código :, animate.addEventListener('repeat', fun)entonces la función funse llamará cada dursegundo. En nuestro caso, cada segundo.

▍Ventajas


  1. Este método funciona incluso si se asigna un estilo al elemento SVG display: none;.
  2. La cuenta regresiva se detiene automáticamente cuando el elemento SVG se elimina del DOM.
  3. La generación de eventos no comienza hasta que la página esté completamente cargada.
  4. El "temporizador" se detiene automáticamente si la pestaña se vuelve inactiva.

▍ Desventajas


  1. Como en el caso de contar intervalos de tiempo usando animación CSS, la aplicación de este método puede parecer incomprensible para otros programadores.
  2. Dependencia de DOM y CSSOM. Es decir, aquí tenemos las mismas características indeseables que ya se han descrito para el método de contar el tiempo usando animación CSS. A saber: la posibilidad de interrupción del "temporizador" debido a otras reglas CSS.
  3. No es compatible con IE y Edge (hasta que el navegador se transfiera de Microsoft a Chromium).
  4. Inexactitud. De acuerdo con mis pruebas, las desviaciones de dicho temporizador del método más preciso pueden ser muy impresionantes de 15 milisegundos. Puede verificar esto usted mismo experimentando con el ejemplo, un enlace al que se proporciona a continuación.
  5. La cuenta regresiva no comienza hasta que la página esté completamente cargada. Es cierto que este "menos" de este método puede llegar a ser un "más" en algunas situaciones.

Ejemplo en Codesandbox

Uso de la API de animaciones web


Web Animations API le permite animar elementos DOM utilizando código JavaScript.

¡Lo interesante es que incluso puedes animar elementos desmontados! Esto le da acceso a los mecanismos de tiempo disponibles en JavaScript puro (y la API web).

Aquí hay una implementación alternativa 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();
  });
}

Claramente, ¿verdad?

▍Ventajas


  1. Una solución autónoma que no requiere interacción con el DOM.
  2. Un programador que no esté familiarizado con este enfoque comprenderá fácilmente el significado del código correspondiente.
  3. "Temporizador" se detiene en una pestaña inactiva.

▍ Desventajas


  1. API de animaciones web: la tecnología aún es experimental. No lo use en producción.
  2. Muy mal soporte del navegador. Es probable que este método funcione solo en cromo.
  3. Con todas las ventajas de esta solución, sin embargo, puede parecerle a alguien lejos de ser intuitivo.
  4. El hecho de que el "temporizador" esté en pausa en una pestaña inactiva puede resultar ser un signo negativo de esta solución si se usa como alternativa setTimeout.
  5. Este método no se puede usar para contar intervalos. Solo un evento está disponible para el programador onfinish.
  6. Baja exactitud. Según mis experimentos, el error puede ser fácilmente ± 5 milisegundos.

→  Ejemplo en Codesandbox

Prima


Para trabajar con el tiempo, puede usar la API de audio web. Esta es otra excelente manera de trabajar con precisión con intervalos y retrasos. Aquí hay un gran artículo al respecto.

Resumen


Entiendo que las técnicas de trabajar con el tiempo que he enumerado aquí pueden beneficiarse lejos de todo. Pero no pude evitar escribir este artículo, porque siempre pensé que setTimeouty setIntervalestas son las únicas formas de trabajo asincrónico con ciertos intervalos de tiempo. Pero en realidad, resultó que esto está lejos de todo. Quién sabe, tal vez alguien tendrá que lidiar con algunas restricciones inusuales al trabajar en un determinado proyecto, con algunas condiciones especiales en las que los métodos de trabajo resaltados aquí pueden resultar útiles con el tiempo.

¡Queridos lectores! ¿En qué situaciones cree que los enfoques basados ​​en el tiempo descritos aquí pueden ser útiles?


All Articles