Web Worker: une application en parallèle

L'objet Worker permet de lancer un script en même temps qu'une page est affichée, fonctionnant de façon asynchrone et pouvant communiquer avec la page.

Le script chargé par le Worker peut ainsi exécuter un traitement long sans bloquer le fonctionnement de la page courante ni les interactions avec l'utilisateur. Un peu comme Ajax, mais en langage JavaScript coté client et non coté serveur.
On utilisera Ajax quand on a besoin de données stockées sur le serveur, et un Worker quand elles sont fournies par l'utilisateur.

Il y une chose à savoir avant tout: créer un Worker consomme beaucoup de ressources: on ne devrait pas en créer plusieurs en même temps si l'on veut que cela fonctionne sur tous les ordinateurs, même les moins puissants.

L'objet Worker

Compatibilité: IE 10, Firefox 31, Chrome 31, Safari 7, Android et iOS récentes.

Dans la page web

Il est très facile de lancer une tâche qui doit fonctionner en parallèle...

var w = new Worker("myscript.js");

On peut alors communiquer avec le script. Pour recevoir les messages qu'il envoie:

w.onmessage = function(evt) {
  alert(evt.data);
}

Remplacez alert par les instructions de votre choix.

Et pour envoyer un message de la page web au script:

w.postMessage("...contenu...");
Dans le script

Le script de son coté utilise des fonctions similaires, mais sans la référence au Worker puisqu'il se trouve à l'intérieur: l'objet Worker est un conteneur dans lequel s'exécute le script.

Pour recevoir des données:

onmessage = function(evt) {
  console.log(evt.data);
}

Pour envoyer des données:

postMessage("...données...");

Démonstration

Pour simplifier la démonstration on utilisera un script très court (le calcul du plus grand diviseur commun) alors qu'en production, seul un traitement long justifierait l'utilisation d'un Worker.

Entrez deux nombres quelconques et cliquez sur Envoi.

Nombre a Nombre b

Plus grand commun dénominateur:

Résultat
Code source dans la page HTML

JavaScript

var w = new Worker("myscript.js");
var a = 0;
var b = 0;

function message() {
  w.postMessage(JSON.stringify( {"a":a,"b":b} ));
}

w.onmessage = function(evt) {
  document.getElementById("result").innerHTML = evt.data;
}

HTML

<form method="post" action="">
Nombre a <input type="text" value="" onchange="a=this.value;">
Nombre b <input type="text" value="" onchange="b=this.value;">
<input type="button" value="Envoi" onclick="message()">
</form>
Code source du fichier myscript.js
function gcd(a,b) {
  while (a!=b)
  {
    if(a>b) a-=b; 
    else    b-=a;
  }
  return a;
}

onmessage = function(evt) {
  var obj = JSON.parse(evt.data);
  var a = obj["a"];
  var b = obj["b"];
  var x = gcd(a, b);
  postMessage(x);
}

L'objet SharedWorker

Compatibilité: Edge, Firefox 31, Chrome 31. Aucun mobile. (En mai 2015).

Un Worker consomme beaucoup de ressources et c'est une des raisons pour lesquelles SharedWorker existe: cela permet à un même script lancé en parallèle d'être utilisé par plusieurs fenêtres ou frames différentes. Une autre raison tout aussi importante est qu'elle leur permet de communiquer entre elles.

Mais l'objet SharedWorker n'est pas supporté par Internet Explorer. Il l'est par le navigateur Edge sous Windows 10.

Il existe aussi d'autres moyens pour échanger des données entres fenêtres et iframes comme on l'a décrit dans l'article: Faire communiquer des iframes.

© 18 mai 2015 Xul.fr