[ HTML5 ] Les Web Workers

Avec la venue de l'HTML5, ont peux trouver toute sorte de chose intéressantes. Dont les APIs qui nous apporte de nombreuses possibilités. Les APIs demandent un minimum de connaissances en JavaScript.

Dans les quelques APIs disponibles, on peut avoir :

  • Les Web Worker, pour tout ce qui est multiprocessus.
  • Le Drag and Drop, afin d'avoir une gestion de déplacement d'élément.
  • La Géolocalisation, un GPS en html5 ?
  • L'intégration de zone graphique avec SVG et Canvas.

Nous allons nous concentrer sur l'application Web Worker, les autres seront pour de prochains articles.

Description :

Les Web Workers permettent au page web d'exécuter simplement du code JavaScript en arrière-plan, c'est à dire indépendamment du thread principal. De cette façon, on pourra faire des calculs ou autre, sans avoir d'interruption lors d'un clic utilisateur par exemple.

Attention les Web Workers étant indépendant des scripts interfaces, ils n'auront pas accès au DOM de la page par exemple les objets 'document', 'window', 'console' ...

Les Workers utilisent les processus comme les systèmes d'exploitation (OS-level thread). Ce qui assure une certaine sécurité dans les gestions des processus à l'instar d'autre technologie.

Les Web Workers par l’exemple :

Au lieu de détailler le fonctionnement des Web Workers comme dans la documentation. Nous allons le voir directement en action avec un exemple. Dans notre cas, nous allons réaliser un afficheur de timeline Twitter. Celui-ci s’actualisera automatiquement.

On commence par le HTML :

index.html

<!DOCTYPE html> 
<html>
    <head>
        <title>TP Web Worker</title>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <script src="js/global.js"></script>
    </head>
    <body>
        <div id="tweets"></div>
    </body>
</html>

Il n’y a pas besoin de grand-chose dans notre “index.html”. On précise que l’on fait de l’html5 avec le doctype simple. Dans le body on rajoute une “div” qui contiendra toute notre timeline de tweets. On ne s’occupera pas du design css dans cet article. On va se concentrer surtout sur le JavaScript qui sera contenu dans “global.js” et dans “twitter.js” (le web worker).

js/global.js

window.onload = function() {
    var twitterWorker = new Worker('js/twitter.js');
}

Voici comment on appelle un Web Worker en JavaScript via le constructeur Worker. On passe en paramètre le lien du JavaScript qui fera le travail du worker. Il faut faire attention au chemin de celui-ci. Si vous regardez bien, mes fichiers “global.js” et “twitter.js” se trouvent dans le même répertoire “js/”. Pour temps, on spécifie le chemin complet du fichier et non le chemin relatif par rapport à “global.js”.

Maintenant avant de continuer, il faut expliquer comment fonctionne la transition d’information entre le worker et le script appelant (la variable ‘twitterWorker’ dans notre cas). Cela est assez simple, ils vont écouter l’évènement onmessage. Cet évènement est reçu lors de l’utilisation de la fonction postMessage.

Si l’on reprend notre exemple, on souhaite avoir les tweets d’une timeline qui s’affiche dans la div d’identifiant ‘tweets’. Pour cela, nous allons récupérer les tweets que le worker nous trouve en définissant un callback pour la méthode onmessage de ‘twitterWorker’. Ce qui nous donne le code suivant :

js/global.js

window.onload = function() {
    var twitterWorker = new Worker('js/twitter.js');

    twitterWorker.onmessage = function(arg) {
        // innerHTML pour avoir le contenu html de l'element selectionné
        document.getElementById('tweets').innerHTML = 
        arg.data + document.getElementById('tweets').innerHTML;
    }
}

Maintenant que notre côté client (global.js) est fini, on va pouvoir s’occuper de traiter les tweets. Oui, pas besoin de plus de ligne. Tout le reste du travail sera pour le worker. Pour le traitement de nos tweets nous allons utiliser l’API REST de Twitter.

js/twitter.js

var lastTweetId = null;

// On oublie pas le paramètre de callback pour faire ce que l'on appel du jsonp
var url = "http://search.twitter.com/search.json?q=WebWorkers&callback=parseJsonToHtml";

// Function spécial pour les web worker pour charger des script externe (du jsonp dans notre cas)
importScripts(url);

setInterval(function(){
    var newUrl = url+"&since_id="+lastTweetId;

    importScripts(newUrl);
}, 10000); // 10000 millisecondes = 10 secondes

La fonction importScripts est mise à disposition pour les Web Workers. Il aura pour but d’importer du code qui sera exécuté par la suite. ImportScripts considère tout ce qu’il importe comme du JavaScript (même si le MIME type ne le spécifie pas). Donc, il faut bien faire attention que la ressource que l’on va chercher est exécutable. D’où notre utilisation ici d’un paramètre qui sera le nom du callback. De cette façon, l’API de twitter va mettre l’object json dans une fonction.

On peut noter l’appel deux fois de l’ImportScripts. Une première fois au chargement de la page. Une deuxième fois pour une exécution toutes les 10 secondes et j’en profite pour spécifier l’identifiant du dernier tweet.

Pour finir notre exemple, il nous reste la fonction de callback, ‘parseJsonToHtml’, à écrire.

js/twitter.js *suite

function parseJsonToHtml(tweets) {
    var html = "";

    var length = tweets.results.length;

    if (length > 0) {
        for (var i = 0; i < length; i++) {
            html += tplTweet(tweets.results[i]);
        }

        lastTweetId = tweets.results[0].id;

        postMessage(html);
    }
}

function tplTweet(tweet) {
    var tpl = "<p>"+tweet.text+"<br /> écrit le "+tweet.created_at+" par @"+tweet.from_user+"";

    return tpl;
}

Pour cette partie, il n’y a rien de bien spécial. On découpe ce que nous renvoie Twitter. S’il y a quelque chose dans ‘results’ on boucle pour appliquer la mise en forme sur chaque tweet. Une fois la boucle finie, on renvoie le tout côté client via la fonction postMessage.

Le résultat : http://demo.brunomaurice.net/html5-web-worker/

Il n’y a pas de style, mais cela fait son travail.

source :
- http://www.w3.org/TR/workers
- https://developer.mozilla.org/en-US/docs/DOM/Using_web_workers
- http://msdn.microsoft.com/en-us/hh549259.aspx
- Les cours de Brice Argenson

Aucun commentaire