Utilisation des Web Workers pour maintenir l'exécution du code en arrière-plan

Considérons un scénario où une application côté élève utilise un minuteur pour une animation de levée de main. Ce minuteur s'exécute toutes les 10 ms pour mettre à jour une animation de comptage à rebours, et après 10 secondes, il notifie le serveur pour annuler l'action. Lorsque l'onglet de l'élève est masqué ou que le navigateur est minimisé, l'exécution du minuteur est suspendue, causant des retards dans l'animation et la communication avec le serveur.

Voici un exemple de code JavaScript qui illustre ce problème :

let compteur = 1000;
function demarrerMinuteur() {
    const maintenant = new Date();
    console.log(maintenant.getMinutes() + ":" + maintenant.getSeconds() + " " + compteur);
    if (compteur > 0) {
        compteur--;
        setTimeout(demarrerMinuteur, 16);
    } else {
        compteur = 0;
    }
}
demarrerMinuteur();

Ce code s'arrête de s'exécuter lorsque la page n'est pas active, ce qui entraîne un comptage à rebours incohérent.

Pour résoudre ce problème, on peut utiliser un Web Worker pour exécuter le minuteur dans un fil d'exécution séparé, indépendant de l'état de la page. Cela gaarntit que le code continue de fonctionner même lorsque la page est en arrière-plan ou minimisée.

La solution consiste à créer un Worker en JavaScript :

const travailleur = new Worker("./js/minuteur.js");

Le fichier minuteur.js contiendrait le code du minuteur, modifié pour fonctionner dans le contexte d'un Worker :

let delai = 1000;
function executerCompteRebours() {
    const temps = new Date();
    const message = temps.getMinutes() + ":" + temps.getSeconds() + " " + delai;
    self.postMessage(message);
    if (delai > 0) {
        delai--;
        setTimeout(executerCompteRebours, 16);
    } else {
        delai = 0;
        self.postMessage("Terminé");
    }
}
executerCompteRebours();

Dans ce code, self.postMessage est utilisé pour envoyer des messages au fil principal, permettant la communication entre le Worker et l'application principale.

Présentation des Web Workers

Les Web Workers offrent un environnement multi-thread pour JavaScript. Ils permettent au fil principal de déléguer des tâches à un Worker s'exécutant en arrière-plan, sans bloquer l'interface utilisateur. Cela améliore les performances pour les tâches intensives en calcul ou à latence élevée. Une fois créé, un Worker reste actif indépendamment des interactions dans le fil principal, mais il doit être fermé après utilisation pour éviter une consommation excessive de ressources.

Points d'attention pour les Web Workers

  • Restriction de même origine : Le script du Worker doit provenir de la même origine que le script principal.
  • Limitations sur le DOM : Les Workers ne peuvent pas accéder aux objets DOM, document, window ou parent. Cependant, ils peuvent utiliser navigator et location.
  • Communication : La communication entre le Worker et le fil principal se fait uniquement via des messages échangés avec postMessage et onmessage.
  • Restrictions script : Les Workers ne supportent pas alert() ou confirm(), mais ils peuvent effectuer des requêtes AJAX via XMLHttpRequest.
  • Restrictions sur les fichiers : Les Workers ne peuvent pas lire des fichiers locaux via le protocole file:// ; les scripts doivent être chargés depuis le réseau.

Ces caractéristiques font des Web Workers une solution robuste pour exécuter des tâches en arrière-plan sans impacter l'expérience utilisateur.

Étiquettes: Web Worker JavaScript Multi-threading Page Visibility API Background Execution

Publié le 11 juin à 22h24