Avez-vous déjà eu besoin d'exécuter du code dans le navigateur qui a pris tant de temps pour exécuter votre application qui ne répond plus pendant un certain temps? Avec les travailleurs Web HTML5, vous n'aurez plus jamais besoin de vivre cela.
Les travailleurs Web vous permettent de séparer le code de longue durée et de l'exécuter indépendamment des autres codes exécutés sur la page. Cela permet à votre interface utilisateur de rester réactive, même lors d'opérations complexes.
Que sont les Web Workers ?
Traditionnellement, JavaScript est un langage monothread. Cela signifie que rien d'autre ne peut s'exécuter pendant qu'un morceau de code est en cours d'exécution. Par exemple, si vous avez du code essayant d'animer un élément DOM, le code essayant de changer une variable doit attendre la fin de l'animation avant de pouvoir s'exécuter.
Les web workers sont des fichiers JavaScript qui s'exécutent dans un thread séparé sans accès direct au DOM.
Une façon de penser aux travailleurs Web est qu'ils sont des morceaux de code qui prennent beaucoup de temps à s'exécuter, donc vous les donnez au navigateur pour qu'il s'exécute en arrière-plan. Étant donné que ce code s'exécute désormais en arrière-plan, il n'affecte pas le JavaScript responsable de votre page Web.
Comme effet secondaire, il ne peut plus interagir directement avec le reste de votre code, de sorte que les web workers n'ont pas accès au DOM. Cependant, de nombreuses autres API de navigateur sont toujours disponibles, notamment les API WebSocket et Fetch.
Les travailleurs Web ne sont cependant pas entièrement isolés du fil principal. Lorsqu'un travailleur a besoin de communiquer avec le thread principal, il peut envoyer un message et le thread principal peut envoyer son propre message en réponse.
Pourquoi les Web Workers ?
Avant les web workers, la seule façon d'exécuter JavaScript qui nécessitait beaucoup de temps dans le navigateur était soit :
- Acceptez que la page ne réponde pas pendant un certain temps.
- Cassez ce code en morceaux asynchrones.
Étant donné qu'une page qui ne répond pas est généralement une mauvaise expérience utilisateur, vous pouvez opter pour l'option asynchrone. Écrire du code de cette manière signifie le diviser en plus petits morceaux que le navigateur peut exécuter alors qu'il ne gère pas l'interface utilisateur. Les éléments doivent être suffisamment petits pour que, si l'interface utilisateur doit être mise à jour, le navigateur puisse terminer l'exécution de l'élément en cours et s'occuper de l'interface utilisateur.
Les travailleurs Web ont été ajoutés à HTML5 pour offrir une meilleure solution à ce problème. Au lieu de vous forcer à faire preuve de créativité avec du code asynchrone, ils vous permettent de séparer proprement une fonction à exécuter dans son propre thread isolé.
Cela a permis aux développeurs d'écrire plus facilement un tel code et a également amélioré l'expérience de l'utilisateur.
Cas d'utilisation pour les Web Workers
Toute application nécessitant beaucoup de calculs côté client pourrait bénéficier des travailleurs Web.
Supposons, par exemple, que votre application souhaite générer un rapport d'utilisation et qu'elle stocke toutes les données sur le client pour des raisons de confidentialité.
Pour générer ce rapport, votre application Web doit récupérer les données, y exécuter des calculs, organiser les résultats et les présenter à l'utilisateur.
Si vous essayiez de le faire dans le thread principal, l'utilisateur serait totalement incapable d'utiliser l'application pendant que l'application traitait les données. Au lieu de cela, vous pouvez déplacer tout ou partie de ce code dans un Web Worker. Cela permet à l'utilisateur de continuer à utiliser l'application pendant que les calculs sont effectués.
Comment utiliser les travailleurs Web en JavaScript
La API de travail Web définit comment utiliser les web workers. L'utilisation de cette API implique la création d'un objet Worker avec le constructeur Worker comme ceci :
soit newWorker = Worker('travailleur.js');
La Ouvrier Le constructeur accepte le nom d'un fichier JavaScript comme paramètre et exécute le fichier dans un nouveau thread. Il renvoie un objet Worker pour permettre au thread principal d'interagir avec le thread de travail.
Les travailleurs interagissent avec le thread principal en envoyant des messages dans les deux sens. Vous utilisez le posterMessage fonction pour envoyer des événements entre le travailleur et le thread principal. Utilisez le sur message écouteur d'événement pour écouter les messages de l'autre partie.
Voici un exemple de code. Tout d'abord, un fil principal pourrait ressembler à ceci :
laisser travailleur = Nouveau Travailleur('travailleur.js')
travailleur.postMessage('Hé!')
travailleur.onmessage = fonction(e) {
console.log('Le fil de travail dit', e.données)
}
Ce thread principal crée un objet worker à partir de worker.js, puis lui envoie un message avec worker.postMessage. Il définit ensuite un écouteur d'événement, similaire dans son concept à un Écouteur d'événements DOM. Un événement se déclenche chaque fois que le travailleur renvoie un message au thread principal, et le gestionnaire enregistre le message du travailleur dans la console.
Le code à l'intérieur du worker (worker.js) a une tâche :
sur message = fonction(e) {
laisser message = e.data ;
console.log('Fil principal dit', message);
postMessage('Salut!')
}
Il écoute tous les messages envoyés depuis le thread principal, enregistre le message dans la console et renvoie un message de retour au thread principal.
Les messages de cet exemple ont tous été des chaînes, mais ce n'est pas une exigence: vous pouvez envoyer presque n'importe quel type de données sous forme de message.
Le genre de travailleurs que vous avez vus jusqu'à présent s'appellent des travailleurs dévoués. Vous ne pouvez y accéder qu'à partir du fichier dans lequel vous les avez créés (ils y sont dédiés). Les travailleurs partagés sont à l'opposé: ils peuvent recevoir et envoyer des messages de plusieurs fichiers. Les travailleurs partagés sont conceptuellement les mêmes que les travailleurs dédiés, mais vous devez les utiliser un peu différemment.
Prenons un exemple. Au lieu d'utiliser le constructeur Worker, chaque fichier qui souhaite utiliser un travailleur partagé doit créer un objet travailleur à l'aide de Travailleurpartagé():
laisser Travailleurpartagé = Nouveau SharedWorker('worker.js')
Les différences ne s'arrêtent pas là cependant. Pour qu'un fichier envoie ou reçoive un message d'un travailleur partagé, il doit le faire en accédant à un Port objet, au lieu de le faire directement. Voici à quoi cela ressemble :
sharedWorker.port.postMessage('Bonjour à tous!')
sharedWorker.port.onMessage = fonction(e) {
console.log('Le travailleur partagé a envoyé', e.données);
}
Vous devez également utiliser l'objet port à l'intérieur du travailleur :
onconnect = fonction(e) {
constante port = e.ports[0];
port.onmessage = fonction(e) {
console.log('Message reçu', e.données)
port.postMessage('Bonjour!');
}
}
La onconnect listener se déclenche chaque fois qu'une connexion à un port se produit (lorsqu'un sur message l'écouteur d'événement est configuré dans le thread principal).
Lorsque cela se produit, le code obtient le port auquel il vient d'être connecté à partir de l'événement de connexion et le stocke dans une variable. Ensuite, le code enregistre le sur message écouteur sur l'objet port. Le code enregistre ensuite le message dans la console et utilise le port pour renvoyer un message au thread principal.
Les travailleurs Web améliorent l'expérience utilisateur
Les Web Workers sont des threads JavaScript qui vous permettent d'exécuter des morceaux de code complexes et de longue durée en arrière-plan. Ce code évitera alors de bloquer l'interface utilisateur. L'utilisation de web workers facilite grandement l'écriture de ce type de code et améliore l'expérience de l'utilisateur de l'application. Vous pouvez créer des Web Workers et interagir avec eux à l'aide de l'API Web Worker.