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

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

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

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.

Les articles les plus populaires du blog

Envie de continuer à lire des articles autour du développement web (entre autres) ? Voici la sélection des articles de mon blog les plus lus par la communauté !

Voir la sĂ©lection 🚀

Recevez les articles de la semaine par e-mail pour ne rien manquer !

S'abonner à la newsletter 📧
Mes formations disponibles 🎓  -5% inclus pour les lecteurs du blog

À propos de l'auteur

Hello, je suis Nicolas Brondin-Bernard, ingénieur web indépendant depuis 2015 passionné par le partage d'expériences et de connaissances.

Aujourd'hui je suis aussi formateur pour dĂ©veloppeurs web juniors, tu peux me contacter sur nicolas@brondin.com, sur mon site ou devenir membre de ma newsletter pour ne jamais louper le meilleur article de la semaine et ĂȘtre tenu au courant de mes projets !


Photo par Henry & Co. sur Unsplash