JavaScript et plus: 4 approches créatives pour mesurer le temps dans les navigateurs

L'auteur de l'article, dont nous publions aujourd'hui la traduction, a décidé de parler de plusieurs façons inhabituelles de mesurer le temps dans les navigateurs. Pour les utiliser, vous aurez besoin d'accéder à diverses API utilisées dans le développement Web, elles ne conviennent donc pas à la plate-forme Node.js. Certes, si quelqu'un a besoin d'une façon inhabituelle de mesurer le temps dans Node.js, nous pensons qu'aprÚs avoir lu ce document, il peut avoir des idées à ce sujet.



Utilisation d'une boucle synchrone infinie dans un travailleur Web (pas dans un travailleur de service)


Étant donnĂ© que les travailleurs Web sont essentiellement des threads exĂ©cutĂ©s dans un navigateur Web, ils peuvent exĂ©cuter des boucles sans fin sans risquer de bloquer le thread principal. Cela vous permet de travailler avec des pĂ©riodes de temps dont la durĂ©e est infĂ©rieure Ă  une milliseconde. Cette prĂ©cision est particuliĂšrement adaptĂ©e aux cas oĂč un travailleur doit prendre des dĂ©cisions qui dĂ©pendent fortement du temps. L'adoption de ces dĂ©cisions peut (avec un trĂšs haut niveau de prĂ©cision) ĂȘtre signalĂ©e au flux principal. Par exemple, vous pouvez dĂ©river quelque chose dans le cas oĂč le nombre de microsecondes qui se sont Ă©coulĂ©es depuis un certain Ă©vĂ©nement est reprĂ©sentĂ© par un nombre premier. Pour travailler avec une prĂ©cision en microsecondes dans le temps, vous pouvez utiliser la mĂ©thode performance.now .

▍Avantages


  1. Précision atteignable exprimée en microsecondes.
  2. .
  3. , , . - .
  4. . , setInterval, terminate , . MDN : « terminate() Worker . , ».

▍


  1. MĂȘme si cette mĂ©thode permet de travailler avec des intervalles de temps infĂ©rieurs Ă  une milliseconde, l'envoi de messages au thread principal fonctionne de maniĂšre asynchrone. Autrement dit, il est impossible d'effectuer certaines actions dans le thread principal avec la mĂȘme prĂ©cision avec laquelle le travailleur dĂ©cide que ces actions doivent ĂȘtre effectuĂ©es.
  2. Cette méthode charge complÚtement le flux, ce qui peut entraßner une augmentation de la consommation de batterie des téléphones.
  3. Cette méthode nécessite le soutien de travailleurs Web.
  4. Une boucle infinie dans un travailleur Web ne s'arrĂȘte pas si l'onglet qui lui est associĂ© est inactif.

→ Exemple sur Codesandbox

Utilisation d'animations CSS pour des événements liés au temps (en particulier - animationiteration)


Cette mĂ©thode consiste Ă  crĂ©er un Ă©lĂ©ment avec une animation sans fin. Ici, vous pouvez essayer d'utiliser l'Ă©lĂ©ment div, mais je dois dire que, comme indiquĂ© au paragraphe 2 de la liste des lacunes de cette mĂ©thode, divil est prĂ©fĂ©rable de ne pas utiliser d' Ă©lĂ©ments Ă  ces fins. Donc, si nous avons un Ă©lĂ©ment avec une animation sans fin, nous pouvons nous abonner Ă  son Ă©vĂ©nement animationiterationet recevoir des notifications aux moments oĂč l'intervalle expire animation-duration.

▍Avantages


  1. Pause automatique si l'onglet du navigateur devient inactif. Dans ce cas, l'Ă©vĂ©nement qui nous intĂ©resse ne se produit tout simplement pas. Par consĂ©quent, vous n'avez pas Ă  vous soucier de rĂ©soudre le problĂšme du traitement de nombreux Ă©vĂ©nements qui se sont accumulĂ©s pendant le temps oĂč l'onglet Ă©tait inactif puis activĂ©.
  2. div DOM. , React-, , . div .
  3. , , . — :

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

▍


  1. . , , .
  2. DĂ©pendance Ă  DOM et CSSOM. D'autres rĂšgles CSS peuvent affecter celles qui dĂ©crivent l'animation. Par consĂ©quent, je vous conseille de crĂ©er une organisation de temporisation pour une sorte de balise prĂ©cĂ©demment inexistante nommĂ©e arbitrairement <just-a-timer-element></<just-a-timer-element>. Peut-ĂȘtre - cela vaut-il la peine de crĂ©er un Ă©lĂ©ment personnalisĂ©, dans lequel le code d'animation CSS est soigneusement cachĂ©? (Ce sont toutes des idĂ©es assez controversĂ©es, en fait).
  3. Cette méthode ne fonctionne pas si l'élément a un style display: none;.
  4. Inexactitude. ConformĂ©ment Ă  mes tests, la prĂ©cision du compte Ă  rebours peut ĂȘtre d'environ 1 ms. Vous, pour savoir exactement comment cela fonctionne pour vous, pouvez expĂ©rimenter avec un exemple, un lien vers lequel est donnĂ© ci-dessous.

→ Exemple sur Codesandbox

Utilisation de la balise svg (animations SMIL)


Jetez un Ɠil Ă  l'Ă©lĂ©ment SVG suivant:

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

Si vous utilisez le code suivant:, animate.addEventListener('repeat', fun)la fonction funsera appelée toutes les dursecondes. Dans notre cas, chaque seconde.

▍Avantages


  1. Cette mĂ©thode fonctionne mĂȘme si un style est attribuĂ© Ă  l'Ă©lĂ©ment SVG display: none;.
  2. Le compte Ă  rebours s'arrĂȘte automatiquement lorsque l'Ă©lĂ©ment SVG est supprimĂ© du DOM.
  3. La génération d'événements ne démarre que lorsque la page est entiÚrement chargée.
  4. Le "temporisateur" est automatiquement mis en pause si l'onglet devient inactif.

▍ InconvĂ©nients


  1. Comme dans le cas du comptage d'intervalles de temps à l'aide d'une animation CSS, l'application de cette méthode peut sembler incompréhensible aux autres programmeurs.
  2. DĂ©pendance Ă  DOM et CSSOM. C'est-Ă -dire que nous avons ici les mĂȘmes fonctionnalitĂ©s indĂ©sirables qui ont dĂ©jĂ  Ă©tĂ© dĂ©crites pour la mĂ©thode de comptage du temps en utilisant l'animation CSS. À savoir - la possibilitĂ© de perturbation du "temporisateur" en raison d'autres rĂšgles CSS.
  3. Il n'est pas pris en charge dans IE et Edge (jusqu'à ce que le navigateur soit transféré de Microsoft vers Chromium).
  4. Inexactitude. ConformĂ©ment Ă  mes tests, les Ă©carts d'un tel temporisateur par rapport Ă  la mĂ©thode la plus prĂ©cise peuvent ĂȘtre trĂšs impressionnants de 15 millisecondes. Vous pouvez le vĂ©rifier vous-mĂȘme en expĂ©rimentant l'exemple, dont le lien est donnĂ© ci-dessous.
  5. Le compte Ă  rebours ne dĂ©marre que lorsque la page est entiĂšrement chargĂ©e. Certes, ce «moins» de cette mĂ©thode peut s'avĂ©rer ĂȘtre un «plus» dans certaines situations.

→ Exemple sur Codesandbox

Utilisation de l'API Web Animations


L'API Web Animations vous permet d'animer des éléments DOM à l'aide de code JavaScript.

La chose intĂ©ressante est que vous pouvez mĂȘme animer des Ă©lĂ©ments non montĂ©s! Cela vous donne accĂšs aux mĂ©canismes de temps disponibles en JavaScript pur (et Ă  l'API Web).

Voici une implémentation alternative 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();
  });
}

Bien, non?

▍Avantages


  1. Une solution autonome qui ne nécessite pas d'interaction avec le DOM.
  2. Un programmeur peu familier avec cette approche comprendra facilement la signification du code correspondant.
  3. "Minuterie" s'arrĂȘte sur un onglet inactif.

▍ InconvĂ©nients


  1. API Web Animations - la technologie est encore expérimentale. Ne l'utilisez pas en production.
  2. Prise en charge trÚs médiocre du navigateur. Cette méthode est susceptible de fonctionner uniquement dans le chrome.
  3. Avec tous les avantages de cette solution, elle peut nĂ©anmoins sembler loin d'ĂȘtre intuitive.
  4. Le fait que la «minuterie» soit suspendue sur un onglet inactif peut s'avĂ©rer ĂȘtre un inconvĂ©nient de cette solution si elle est utilisĂ©e comme alternative setTimeout.
  5. Cette mĂ©thode ne peut pas ĂȘtre utilisĂ©e pour compter les intervalles. Seul un Ă©vĂ©nement est disponible pour le programmeur onfinish.
  6. PrĂ©cision faible. D'aprĂšs mes expĂ©riences, l'erreur peut facilement ĂȘtre de ± 5 millisecondes.

→  Exemple sur Codesandbox

Prime


Pour travailler avec le temps, vous pouvez utiliser l'API Web Audio. C'est une autre excellente façon de travailler avec précision avec des intervalles et des retards. Voici un excellent article à ce sujet.

Sommaire


Je comprends que les techniques de travail avec le temps que j'ai Ă©numĂ©rĂ©es ici peuvent bĂ©nĂ©ficier de loin. Mais je ne pouvais pas m'empĂȘcher d'Ă©crire cet article, car j'ai toujours pensĂ© que setTimeoutet setInterval- ce sont les seules façons de travailler asynchrone avec certains intervalles de temps. Mais en rĂ©alitĂ©, il s'est avĂ©rĂ© que c'est loin d'ĂȘtre tout. Qui sait, peut-ĂȘtre que quelqu'un devra faire face Ă  des restrictions inhabituelles lorsqu'il travaillera sur un certain projet, avec des conditions spĂ©ciales dans lesquelles les mĂ©thodes de travail mises en Ă©vidence ici peuvent s'avĂ©rer utiles au fil du temps.

Chers lecteurs! Dans quelles situations pensez-vous que les approches temporelles dĂ©crites ici peuvent ĂȘtre utiles?


All Articles