Les Web Workers
Du multithreadé à la demande[Web Workers simples]

Le , par TiranusKBX, Expert confirmé
Présentation
Les Web Workers sont un mécanisme/API grâce auquel les instructions d'un script peuvent être exécutés dans un thread parallèle au thread d'exécution principal d'une application web.
De ce fait il est possible de les utiliser pour les traitements lourds/long potentiellement bloquant, permettant de ne pas bloquer le thread principal et donc que la page ne freeze pas.
La vous me dite
Mais les fonction eval(), setTimeout() et setInterval() ne créent pas déjà un thread parallèle ?

Et bien la réponse est non car :
  • eval() : il faut savoir que cette fonction peut retourner une valeur de retour(définie par le code parsé) donc non multi-thread
  • setTimeout() : se retrouve dans la zone de l’interprétation des événements
  • setInterval() : se retrouve dans la zone de l’interprétation des événements


Limitations


Et oui tout grand pouvoir qu'il soit le multithreading Javascript
à des limitation par souci de sécurité d'accès aux données navigateur

un Worker n'à pas accès à :
  1. Objet window
  2. Objet document
  3. Objet parent
  4. Plus généralement les Objets DOM


un Worker à accès en lecture seulement :
  1. Objet navigator
  2. Objet location
Mise en pratique
Initialisation
En premier lieux nous allons utiliser la méthode Worker() pour créer un web worker;
Un Worker pouvant en créer un autre je parlerait donc par la suite de parent pour l'appelant pour ne pas se limiter au thread principal
Les Workers sont crées avec le code venant d'un fichier javascript que celui-ci vas charger puis exécuter,
si vous souhaiter exécuter du code écris dans un fichier déjà chargé vous devrez créer un objet Blob et passer à la méthode Worker() l'URL de ce Blob.
Pour les URL relative depuis un code exécuté en thread principal le chemin relatif est depuis le dossier de la page,
depuis un Worker c'est depuis le dossier dans lequel est son fichier et pour du code d'un Blob les chemins relatifs sont caducs
Code Javascript : Sélectionner tout
worker = Worker("myworker.js")
Communication
Comme vous pouvez le voir sur l'image à droite de ce texte
pour la communication avec le tread il faut utiliser la commande postMessage() et les données envoyées peuvent être de n'importe quel format(String, Number, Object, Array, ...)
Pour vous expliquer comment procéder rien de mieux qu'un petit exemple
coté parent:
Code Javascript : Sélectionner tout
1
2
3
var worker = new Worker('worker.js'); 
worker.addEventListener('message', function(e) {alert("Worker say : "+e.data);}, false); 
worker.postMessage("Mon petit message");

coté worker.js:
Code Javascript : Sélectionner tout
1
2
3
4
5
6
  
var count = 0; 
self.addEventListener('message', function(e) { 
    count = count + 1; 
    postMessage(e.data+" = message n°"+count); 
},false);
Pour résultat de ce petit exemple vous auriez une fenêtre comme ce qui suis:
Extension du code
Imaginons que votre Worker soit pour du traitement plutôt lourd et que pour des raisons évidente de maintenabilité(les fichier de plus de 500 lignes ça commence à poser soucis ^^)
vous le scindé en plusieurs fichier, et bien pas de soucis, la fonction importScripts() est la !
Pour les URL relatives c'est depuis le dossier dans lequel est le fichier du Worker et pour du code d'un Blob les chemins relatifs sont caducs
Code Javascript : Sélectionner tout
1
2
3
importScripts();                        /* Importe strictement rien */ 
importScripts('foo.js');                /* Importe "foo.js" */ 
importScripts('foo.js', 'bar.js');      /* Importe les 2 scripts */

Suicide ou meurtre ?
Pour arrêter un Web Worker vous avez 2 solutions
  1. La méthode douce avec close() depuis le Worker
  2. la méthode musclée depuis le parent avec objetworker.terminate()


Conclusion
Il n'est donc pas difficile de mettre en place des Web Workers, le plus compliqué étant de faire bien attention au traitement des données envoyées en message.
De plus voici une petite recommandation: n'en abusez pas sauf si c'est vôtre trip de faire freezer les pc chargeant votre page web
Il existe aussi une version partagée des Web Workers(pour plusieurs pages en même temps) mais comme il on un degré de complexité plus important je les aborderait dans un prochain article

Source MDN


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :
Responsable bénévole de la rubrique JavaScript : Xavier Lecomte -