Jusqu'à présent, le contenu de ce cours était essentiellement axé sur des concepts tels que les considérations générales relatives aux performances HTML, les indications de ressources, l'optimisation de différents types de ressources pour améliorer le temps de chargement initial de la page et la réactivité aux entrées utilisateur, ainsi que le chargement différé de ressources spécifiques.
Toutefois, un aspect des performances concernant JavaScript n'a pas encore été abordé dans ce cours. Le rôle des workers Web dans l'amélioration de la réactivité aux entrées est abordé dans ce module et dans le prochain module.
JavaScript est souvent décrit comme un langage à thread unique. En pratique, il s'agit du thread principal, qui est le thread unique dans lequel le navigateur effectue la majeure partie du travail que vous voyez dans le navigateur. Il s'agit, entre autres, de tâches liées à l'écriture de scripts, à certains types de tâches de rendu, à l'analyse HTML et CSS, ainsi qu'à d'autres tâches destinées à l'utilisateur qui améliorent l'expérience utilisateur. En réalité, les navigateurs utilisent d'autres threads pour effectuer des tâches pour lesquelles vous, le développeur, n'avez généralement pas un accès direct, comme les threads GPU.
En ce qui concerne JavaScript, vous êtes généralement limité à travailler sur le thread principal, mais seulement par défaut. Il est possible d'enregistrer et d'utiliser des threads supplémentaires en JavaScript. La fonctionnalité qui permet le multithreading en JavaScript est connue sous le nom d'API Web Workers.
Les nœuds de calcul Web sont utiles lorsque vous avez des tâches coûteuses en calcul qui ne peuvent tout simplement pas être exécutées sur le thread principal sans entraîner de longues tâches qui rendent la page non réactive. Ces tâches peuvent certainement avoir une incidence sur l'interaction avec Next Paint (INP) de votre site Web. Il peut donc être utile de savoir quand certaines tâches peuvent être entièrement effectuées en dehors du thread principal. Cela permet de libérer de l'espace pour d'autres tâches sur le thread principal afin d'accélérer les interactions utilisateur.
Ce module et la démonstration suivante présentant un cas d'utilisation concret traitent des workers Web. La démonstration elle-même montre comment utiliser un nœud de calcul Web pour lire des métadonnées d'image à partir d'un fichier JPEG en dehors du thread principal, et comment renvoyer ces métadonnées au thread principal pour que l'utilisateur les voie.
Lancement d'un nœud de calcul Web
Un worker Web est enregistré en instanciant la classe Worker
. Vous spécifiez alors l'emplacement du code du nœud de calcul Web, que le navigateur charge, puis crée un thread. Le thread résultant est souvent appelé thread de nœud de calcul.
const myWebWorker = new Worker('/js/my-web-worker.js');
Dans le fichier JavaScript du nœud de calcul (my-web-worker.js
dans ce cas), vous pouvez écrire du code qui s'exécute ensuite dans un thread de nœud de calcul distinct.
Limites des workers Web
Contrairement à JavaScript qui s'exécute sur le thread principal, les workers Web ne disposent pas d'un accès direct au contexte window
et ont un accès limité aux API qu'il fournit. Les nœuds de calcul Web sont soumis aux contraintes suivantes:
- Les Web workers ne peuvent pas accéder directement au DOM.
- Les nœuds de calcul Web peuvent communiquer avec le contexte
window
via un pipeline de messagerie, ce qui signifie qu'ils peuvent accéder indirectement au DOM d'une manière ou d'une autre. - Le champ d'application du nœud de calcul Web est
self
, et nonwindow
. - Le champ d'application du nœud de calcul Web a accès aux primitives et aux constructions JavaScript, ainsi qu'à des API telles que
fetch
et à un grand nombre d'autres API.
Comment les workers Web communiquent avec le window
Un nœud de calcul Web peut communiquer avec le contexte window
du thread principal via un pipeline de messagerie. Ce pipeline vous permet de transférer des données
vers et depuis le thread principal et le worker Web. Pour envoyer des données d'un nœud de calcul Web au thread principal, vous devez configurer un événement message
dans le contexte du nœud de calcul Web (self
).
// my-web-worker.js
self.addEventListener("message", () => {
// Sends a message of "Hellow, window!" from the web worker:
self.postMessage("Hello, window!");
});
Ensuite, dans un script situé dans le contexte window
du thread principal, vous pouvez recevoir le message du thread de nœud de calcul Web à l'aide d'un autre événement message
:
// scripts.js
// Creates the web worker:
const myWebWorker = new Worker('/js/my-web-worker.js');
// Adds an event listener on the web worker instance that listens for messages:
myWebWorker.addEventListener("message", ({ data }) => {
// Echoes "Hello, window!" to the console from the worker.
console.log(data);
});
Le pipeline de messagerie d'un nœud de calcul Web est une sorte de mécanisme de secours par rapport au contexte du nœud de calcul Web. Il vous permet d'envoyer des données au window
à partir du worker Web, que vous pouvez utiliser pour mettre à jour le DOM, ou d'effectuer d'autres tâches à effectuer sur le thread principal.
Tester vos connaissances
Sur quel thread est exécuté un nœud de calcul Web ?
À quels éléments un nœud de calcul Web peut-il accéder ?
window
, y compris fetch
.
window
, mais uniquement de façon indirecte.Comment un nœud de calcul peut-il accéder au contexte "window" (fenêtre) ?
window
.
window
, sous aucun moyen.
postMessage
dans le contexte du nœud de calcul Web (self
).
À suivre: un cas d'utilisation concret d'un travailleur Web
Dans le module suivant, un cas d'utilisation concret d'un nœud de calcul Web est détaillé et présenté. Dans ce module, un nœud de calcul Web récupère un fichier JPEG à partir d'une URL donnée et lit ses métadonnées Exif. Ces données sont ensuite renvoyées au thread principal pour être présentées à l'utilisateur.