Qu'est-ce qu'un Web Worker et comment s'en servir ?

Comment lancer de gros calculs en Javascript sans faire planter le navigateur.

Article publié le 06/01/2022, dernière mise à jour le 19/09/2023

Pour bien comprendre ce qu'est un Web Worker, il faut d'abord comprendre comment Javascript utilise la capacité de calcul de votre processeur central.

Votre CPU (Central Processing Unit) est le circuit intégré dans votre machine qui va effectuer tous les calculs et opérations demandé par le système, les applications et autres.

À l'exception des calculs de rendus graphiques qui sont en partie délégués à votre GPU, aussi appelé carte graphique.

Un CPU est décomposé en plusieurs coeurs (pour la plupart) qui vont chacun travailler de manière simultanée mais physiquement indépendante, comme si votre machine était équipée de plusieurs processeurs distincts.

Chaque cœur va alors découper ses flux de calculs en différents threads : un thread est une séquence d'instructions qui peut être exécutée de manière indépendante du reste de manière logique (et non plus physique).

Javascript est un langage "single-threaded", signifiant qu'il n'utilise qu'un seul et unique thread pour toute son exécution (sa boucle d'évènement et sa pile mémoire), ce qui signifie que si l'on exécute un calcul prenant beaucoup de ressource, toute l'application risque de ne plus répondre pendant un certains temps, jusqu'à ce que le navigateur vous propose d'arrêter le script bloquant.

Mais heureusement, les web workers sont là pour résoudre ce problème !

Explications

Un worker est donc un script que le navigateur va exécuter dans un thread séparé du thread principal (gérant l'application Javascript ainsi que l'UI de la page) afin de conserver toutes les performances de la page.

Comme le worker travaille dans un environnement séparé, il ne peut communiquer de manière direct avec l'application Javascript et toutes les communications devront donc passer par des évènements.

Il est important de comprendre que le worker n'a pas accès à la page et est uniquement dédié à du calcul, de la gestion d'entrées/sorties (I/O) ou des traitement de données en dehors de toute interaction graphique.

Par exemple la variable window globale ne sera jamais accessible depuis un worker, mais la Web API XMLHTTPRequest reste, elle, accessible.

Pour des informations plus détaillées, je vous conseiller d'aller consulter la documentation sur le site de Mozilla

Maintenant passons à la pratique avec un exemple !

En pratique

Nous allons découvrir comment créer un web worker et comment gérer la communication entre le worker et le script principal, vous allez voir que la démarche est très simple.

Création du web worker

//main.js

/* Checks if Web Worker feature is available */
if (window.Worker) {
  /* Loads the dedicated script into a new thread */
  let myWorker = new Worker('worker.js');
  //...
} else {
  alert("Web Worker not available");
}

Communication avec le web worker

Toute la communication fonctionne par des évènements, que ce soit pour envoyer des données ou demander au worker d'effectuer une tâche précise.

//main.js

/* After myWorker is initialized we start listening to any data coming from the worker */

myWorker.onmessage = function(e) {
  console.log('Message received from worker:',e.data;);
}

/* To pass data/instructions to the worker, simply do */
myWorker.postMessage("do_something");
//worker.js

onmessage = function(e) {
  console.log('Message received from main script:', e.data);
}

/* Following message will be sent as soon as the worker is started */
postMessage("worker_initialized");

Cloturer le web worker

Lorsque vous aurez terminé d'utiliser votre web worker, vous pourrez terminer son exécution en appelant la méthode suivante :

myWorker.terminate();

Un exemple concret

Si pour complètement comprendre l'utilité des web workers vous avez besoin d'un exemple concret, je vous ai préparé un dépôt Github avec une démo en ligne.

Cette démo consiste en un calcul simple mais lourdement implémenté, exécutable avec ou sans web worker pour que vous voyez bien la différence : https://nicolasbrondin.github.io/basic-web-worker-extension/

N'hésitez pas à réutiliser le code source pour implémenter votre propre worker de manière simple !

J'espère que cet article vous aura été utile, et à bientôt sur le blog.


Henry & Co. sur Unsplash

Vous avez terminé l'article ?

Commentaires (0)

pour laisser un commentaire

Aucun commentaire pour l'instant