[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/fr/docs/Web/API/HTML_DOM_API/Microtask_guide/In_depth [Back]  [Original]

Aller plus loin : Les microtches et l'environnement d'excution JavaScript - Les API Web | MDN

Cette page a t traduite partir de l'anglais par la communaut. Vous pouvez contribuer en rejoignant la communaut francophone sur MDN Web Docs.

View in English Always switch to English

Aller plus loin : Les microtches et l'environnement d'excution JavaScript

Lorsque vous dboguez ou, ventuellement, lorsque vous essayez de dterminer la meilleure approche pour rsoudre un problme autour du temps d'excution et de la planification des tches et des microtches, il y a des lments sur le fonctionnement interne de l'environnement d'excution JavaScript qui peuvent tre utiles comprendre.

JavaScript est un langage intrinsquement monoprocessus. Il a t conu une poque o ce choix tait positif ; il y avait peu d'ordinateurs multiprocesseurs accessibles au grand public, et la quantit de code que JavaScript devait grer tait relativement faible ce moment-l.

Avec le temps, bien sr, nous savons que les ordinateurs ont volu en systmes puissants curs multiples, et JavaScript est devenu l'un des langages les plus utiliss dans le monde informatique. Un grand nombre des applications les plus populaires reposent au moins en partie sur du code JavaScript. Pour accompagner cela, il a t ncessaire de trouver des moyens permettant aux projets de dpasser les contraintes d'un langage monoprocessus.

En commenant par l'ajout des temporisations et des intervalles dans l'API Web (setTimeout() et setInterval()), l'environnement JavaScript fourni par les navigateurs Web s'est progressivement enrichi de fonctionnalits puissantes permettant la planification des tches, le dveloppement d'applications multiprocessus, et ainsi de suite. Pour comprendre o queueMicrotask() intervient ici, il est utile de comprendre comment l'environnement d'excution JavaScript fonctionne lors de la planification et de l'excution du code.

Dans cet article

Contextes d'excution JavaScript

Note : Ces dtails ne sont gnralement pas importants pour la plupart des dveloppeureuses JavaScript. Cette information est fournie pour expliquer pourquoi les microtches sont utiles et comment elles fonctionnent ; si cela ne vous intresse pas, vous pouvez passer cette section et y revenir plus tard si besoin.

Lorsqu'un fragment de code JavaScript s'excute, il s'excute dans un contexte d'excution. Il existe trois types de code qui crent un nouveau contexte d'excution :

  • Le contexte global est le contexte d'excution cr pour excuter le corps principal de votre code ; c'est--dire tout code qui existe en dehors d'une fonction JavaScript.
  • Chaque fonction s'excute dans son propre contexte d'excution. On parle souvent de  contexte local .
  • L'utilisation de la fonction dconseille eval() cre galement un nouveau contexte d'excution.

Chaque contexte est, en substance, un niveau de porte dans votre code. Lorsqu'un de ces segments de code commence s'excuter, un nouveau contexte est construit pour l'excuter ; ce contexte est ensuite dtruit lorsque le code quitte ce segment. Considrez le programme JavaScript ci-dessous :

js
const elemSortie = document.getElementById("output");

const langueUtilisateurs = {
  Mike: "en",
  Teresa: "es",
};

function saluerUtilisateur(utilisateur) {
  function salutationLocale(utilisateur) {
    let salutation;
    const langue = langueUtilisateurs[utilisateur];

    switch (langue) {
      case "es":
        salutation = `Hola, ${utilisateur}!`;
        break;
      case "en":
      default:
        salutation = `Hello, ${utilisateur}!`;
        break;
    }
    return salutation;
  }
  elemSortie.innerText += `${salutationLocale(utilisateur)}\n`;
}

saluerUtilisateur("Mike");
saluerUtilisateur("Teresa");
saluerUtilisateur("Veronica");

Ce court programme contient trois contextes d'excution, certains tant crs et dtruits plusieurs fois au cours de l'excution du programme. chaque cration de contexte, celui-ci est plac sur la pile des contextes d'excution. Lorsqu'il se termine, le contexte est retir de la pile.

  • Au dmarrage du programme, le contexte global est cr.

    • Lorsque saluerUtilisateur("Mike") est atteint, un contexte est cr pour la fonction saluerUtilisateur() ; ce contexte d'excution est ajout la pile des contextes d'excution.

      • Lorsque saluerUtilisateur() appelle salutationLocale(), un autre contexte est cr pour excuter cette fonction. Lorsque cette fonction retourne, le contexte de salutationLocale() est retir de la pile d'excution et dtruit. L'excution du programme reprend avec le prochain contexte trouv sur la pile, qui est saluerUtilisateur() ; cette fonction reprend l o elle s'tait arrte.
      • La fonction saluerUtilisateur() retourne et son contexte est retir de la pile et dtruit.
    • Lorsque saluerUtilisateur("Teresa") est atteint, un contexte est cr pour elle et ajout la pile.

      • Lorsque saluerUtilisateur() appelle salutationLocale(), un autre contexte est cr pour excuter cette fonction. Lorsque cette fonction retourne, le contexte de salutationLocale() est retir de la pile d'excution et dtruit. saluerUtilisateur() continue s'excuter l o elle s'tait arrte.
      • La fonction saluerUtilisateur() retourne et son contexte est retir de la pile et dtruit.
    • Lorsque saluerUtilisateur("Veronica") est atteint, un contexte est cr pour elle et ajout la pile.

      • Lorsque saluerUtilisateur() appelle salutationLocale(), un autre contexte est cr pour excuter cette fonction. Lorsque cette fonction retourne, le contexte de salutationLocale() est retir de la pile d'excution et dtruit.
      • La fonction saluerUtilisateur() retourne et son contexte est retir de la pile et dtruit.
  • Le programme principal se termine et son contexte d'excution est retir de la pile d'excution ; comme il n'y a plus de contextes sur la pile, l'excution du programme prend fin.

En utilisant les contextes d'excution de cette manire, chaque programme et chaque fonction peuvent avoir leur propre ensemble de variables et d'autres objets. Chaque contexte suit galement la prochaine ligne du programme excuter et d'autres informations essentielles son fonctionnement. En utilisant les contextes et la pile de contextes de cette faon, il est possible de grer de nombreux aspects fondamentaux du fonctionnement d'un programme, y compris les variables locales et globales, les appels et retours de fonctions, et ainsi de suite.

Une remarque particulire sur les fonctions rcursives c'est--dire les fonctions qui s'appellent elles-mmes, parfois sur plusieurs niveaux de profondeur ou de rcursion : chaque appel rcursif la fonction cre un nouveau contexte d'excution. Cela permet l'environnement d'excution JavaScript de suivre les niveaux de rcursion et le retour des rsultats travers cette rcursion, mais cela signifie aussi qu' chaque rcursion, plus de mmoire est ncessaire pour crer le nouveau contexte.

Execute, JavaScript, execute !

Pour excuter du code JavaScript, le moteur d'excution maintient un ensemble d'agents pour excuter le code JavaScript. Chaque agent est compos d'un ensemble de contextes d'excution, de la pile des contextes d'excution, d'un processus principal, d'un ensemble pour tout processus supplmentaire pouvant tre cr pour grer les travailleurs, d'une file de tches et d'une file de microtches. l'exception du processus principal que certains navigateurs partagent entre plusieurs agents chaque composant d'un agent est unique cet agent.

Nous allons examiner plus en dtail le fonctionnement du moteur d'excution.

Boucles d'vnements

Chaque agent est pilot par une boucle d'vnements, qui est traite de faon rpte. chaque itration, elle excute au maximum une tche JavaScript en attente, puis toutes les microtches en attente, puis effectue tout rendu ou affichage ncessaire avant de recommencer.

Le code de votre site ou application s'excute dans le mme processus, partageant la mme boucle d'vnements, que l'interface utilisateur du navigateur Web lui-mme. Il s'agit du processus principal, et en plus d'excuter le corps principal de votre site, il gre la rception et la distribution des vnements utilisateur et autres, le rendu et l'affichage du contenu web, etc.

La boucle d'vnements pilote donc tout ce qui se passe dans le navigateur en ce qui concerne l'interaction avec l'utilisateur, mais plus important pour notre propos ici, elle est responsable de la planification et de l'excution de chaque morceau de code qui s'excute dans son processus.

Il existe trois types de boucle d'vnements :

Boucle d'vnements de fentre

La boucle d'vnements de fentre est celle qui pilote toutes les fentres partageant une mme origine (bien qu'il existe d'autres limites, comme dcrit ci-dessous).

Boucle d'vnements de travailleur

Une boucle d'vnements de travailleur est celle qui pilote un travailleur ; cela inclut toutes les formes de travailleurs, y compris les web workers, shared workers, et service workers. Les travailleurs sont conservs dans un ou plusieurs agents distincts du  code principal  ; le navigateur peut utiliser une seule boucle d'vnements pour tous les travailleurs d'un type donn ou plusieurs boucles pour les grer.

Boucle d'vnements de worklet

Une boucle d'vnements worklet est la boucle d'vnements utilise pour piloter les agents qui excutent le code des worklets pour un agent donn. Cela inclut les worklets de type Worklet et AudioWorklet.

Plusieurs fentres charges depuis la mme origine peuvent fonctionner sur la mme boucle d'vnements, chacune ajoutant des tches la boucle pour que leurs tches prennent tour tour le processeur. Gardez l'esprit que dans le langage web, le mot  fentre  signifie en ralit  conteneur au niveau du navigateur dans lequel le contenu web s'excute , incluant une fentre relle, un onglet ou un cadre.

Il existe des circonstances spcifiques dans lesquelles ce partage d'une boucle d'vnements entre fentres ayant une origine commune est possible, telles que :

  • Si une fentre en a ouvert une autre, elles partagent probablement une boucle d'vnements.
  • Si une fentre est en ralit un conteneur dans un <iframe>, elle partage probablement une boucle d'vnements avec la fentre qui la contient.
  • Les fentres partagent le mme processus dans une implmentation de navigateur web multiprocessus.

Les dtails peuvent varier d'un navigateur l'autre, selon leur implmentation.

Tasks vs. microtasks

A task is anything scheduled to be run by the standard mechanisms such as initially starting to execute a script, asynchronously dispatching an event, and so forth. Other than by using events, you can enqueue a task by using setTimeout() or setInterval().

The difference between the task queue and the microtask queue is simple but very important:

  • When a new iteration of the event loop begins, the runtime executes the next task from the task queue. Further tasks and tasks added to the queue after the start of the iteration will not run until the next iteration.
  • Whenever a task exits and the execution context stack is empty, all microtasks in the microtask queue are executed in turn. The difference is that execution of microtasks continues until the queue is emptyeven if new ones are scheduled in the interim. In other words, microtasks can enqueue new microtasks and those new microtasks will execute before the next task begins to run, and before the end of the current event loop iteration.

Problmes

Parce que votre code s'excute dans le mme processus, utilisant la mme boucle d'vnements, que l'interface utilisateur du navigateur, si votre code bloque ou entre dans une boucle infinie, le navigateur lui-mme sera bloqu. Mme des performances lentes, qu'elles soient causes par un bogue ou par un travail complexe effectu par votre code, peuvent rendre le navigateur lent pour l'utilisateurice.

Lorsque plusieurs programmes et plusieurs objets de code dans ces programmes essaient de fonctionner en mme temps, en plus d'un navigateur qui a aussi besoin de temps processeur sans parler du temps pour afficher et dessiner le site et sa propre interface, grer les vnements utilisateur, etc. tout devient beaucoup trop facilement satur aujourd'hui.

Solutions

L'utilisation des web workers, qui permettent au script principal d'excuter d'autres scripts dans de nouveaux processus, aide attnuer ce problme. Un site ou une application bien conue utilise des travailleurs pour effectuer toute opration complexe ou longue, laissant le processus principal faire le moins de travail possible, au-del de la mise jour, de la disposition et de l'affichage de la page web.

Cela est encore amlior par l'utilisation de JavaScript asynchrone et de techniques telles que promesses pour permettre au code principal de continuer s'excuter en attendant les rsultats d'une requte. Cependant, le code s'excutant un niveau plus fondamental comme le code d'une bibliothque ou d'un framework peut avoir besoin d'un moyen de planifier l'excution du code un moment sr tout en restant sur le processus principal, indpendamment des rsultats d'une requte ou d'une tche.

Les microtches sont une autre solution ce problme, offrant un degr d'accs plus fin en permettant de planifier l'excution du code avant le dbut de la prochaine itration de la boucle d'vnements, au lieu d'attendre la suivante.

La file de microtches existe depuis un certain temps, mais elle a historiquement t utilise uniquement en interne pour piloter des lments comme les promesses. L'ajout de queueMicrotask(), qui l'expose aux dveloppeureuses web, cre une file unifie pour les microtches qui est utilise partout o il est ncessaire de pouvoir planifier l'excution du code en toute scurit lorsqu'il n'y a plus de contextes d'excution sur la pile des contextes d'excution JavaScript. Sur plusieurs instances et dans tous les navigateurs et environnements JavaScript, un mcanisme de file standardis signifie que ces microtches fonctionneront de manire fiable dans le mme ordre, vitant ainsi des bogues potentiellement difficiles dtecter.

Voir aussi


Web Proxy Viewer  |  New URL  |  Original Page