Maison  >  Article  >  interface Web  >  Tout ce que vous devez savoir sur les web Workers pour commencer.

Tout ce que vous devez savoir sur les web Workers pour commencer.

DDD
DDDoriginal
2024-10-31 21:07:29911parcourir

Récemment, j'ai bricolé des Web Workers et ceci est un guide complet sur tout ce que vous devez savoir pour commencer à utiliser les Web Workers.

Si vous souhaitez ignorer la lecture du blog et extraire le code à la place, voici le référentiel github qui contient tous les extraits.

Référentiel Github Web Worker

 

Table des matières

  • Idées fausses courantes
  • Configuration de base des Web Workers
    • Configuration de Web Worker avec JavaScript natif
    • Configuration des Web Workers avec Comlink
  • Comment vérifier si mon travailleur a été correctement enregistré ?
  • Lectures complémentaires

 
 

Idées fausses courantes

Donc, ce qui m'a poussé à explorer les Web Workers, c'est que sur une plate-forme sur laquelle je construisais, une tâche lourde en termes de calcul bloquait l'interface utilisateur.
Alors je me suis dit : « Hein, d'accord, comment faire pour que cela ne bloque pas l'interface utilisateur » ? Dois-je utiliser setTimeout pour m'assurer que tout le code du thread principal est terminé, après quoi la tâche lourde en termes de calcul peut s'exécuter ?

Voici donc l'idée fausse : utiliser setTimeout ne signifie pas que l'interface utilisateur ne sera pas bloquée. Oui, tout ce qui se trouve sur le thread principal sera exécuté avant l'exécution du rappel setTimeout. Cependant, ce rappel s'exécute dans le thread principal lui-même lorsqu'il est retiré de la file d'attente des tâches de macro, rendant ainsi l'interface utilisateur insensible.

Pour en savoir plus sur le fonctionnement de setTimeout, voici quelques références —

  • JavaScript asynchrone et boucle d'événements à partir de zéro - Akshay Saini
  • Boucle d'événements, API Web, file d'attente de tâches - Lydia Hallie

 
 

Configuration de base des Web Workers

JavaScript est intrinsèquement un « langage à thread unique », mais les Web Workers nous permettent d'exécuter du code lourd en termes de calcul dans un thread séparé.

Avant de commencer, voici quelques points à noter -

  • Les travailleurs Web ne peuvent pas interagir avec le DOM
  • La portée du Web Worker est auto, plutôt que fenêtre.
  • Les ouvriers sont relativement lourds et ne sont pas destinés à être utilisés en grand nombre. Par exemple, il serait inapproprié de lancer un travailleur pour chaque pixel d'une image de quatre mégapixels. [Réf - Spécification HTML]
  • De plus, un travailleur Web ne consiste pas à faire en sorte que quelque chose prenne 2 secondes au lieu de 4 secondes, il s'agit de faire cette chose avec le DOM gelé pendant 0 seconde. [Réf - Les Web Workers sont lents et ce n'est pas grave - Calvin Metcalf]
  • Les travailleurs peuvent à leur tour engendrer de nouveaux travailleurs, à condition que ces travailleurs soient hébergés dans la même origine que la page parent. [Réf – MDN]

 

Web Worker utilisant JavaScript natif

  1. Créez un nouveau fichier JavaScript contenant le code que vous souhaitez exécuter dans le thread de travail. (disons travailleur.js)
  2. Dans le script principal, instanciez le travailleur -
const worker = new Worker("./worker.js")

Remarque : worker.js n'est pas un module et ne peut pas utiliser d'instructions d'importation. encore. :')

Pour utiliser worker.js comme module, spécifiez type: module dans l'option du constructeur.

const worker = new Worker("./worker.js")
  1. Les données sont envoyées entre les travailleurs via un système de messages : les deux parties envoient leurs messages à l'aide de la méthode postMessage() et répondent aux messages via le gestionnaire d'événements onmessage
  2. Pour transmettre des objets complexes avec des références cycliques dans postMessage(), utilisez la méthode structuréClone.
  3. Pour mettre fin à un Web Worker, utilisez la méthode de terminaison de l'API Worker. Cela n'offre pas au travailleur la possibilité de terminer ses opérations en cours ; on l'arrête aussitôt.
const worker = new Worker('./worker.js', { type: 'module' })

 
Rassembler tout cela

Voyons maintenant à quoi ressemble notre code après l'intégration des web Workers.

Code du fil principal :

worker.terminate() 

Code du fil de travail :

// ...
function workerFunction() {
  // Don't spin up a new worker instance if the process has already been started.
  if (statusElement.textContent !== PROCESS_STATUS.PROCESSING && window.Worker) {
    const worker = new Worker('./worker.js', {
      type: 'module'
    })

    // Sending 10000000000000 to the web worker
    worker.postMessage(10000000000000)

    statusElement.textContent = PROCESS_STATUS.PROCESSING

    // This piece of code is executed after worker finishes its task and returns data. 
    worker.onmessage = function (event) {
      statusElement.textContent = event.data
    }
  }
}
// ...

Et le résultat :

Lorsque nous exécutons l'application, vous remarquerez que la tâche lourde en termes de calcul est exécutée sans bloquer l'interface utilisateur.

 

Configuration de Web Worker avec Comlink

Comlink est une petite bibliothèque (1,1 ko), elle supprime la barrière mentale liée à la réflexion sur la logique post-message.

À un niveau plus abstrait, il s'agit d'une implémentation RPC pour postMessage et ES6 Proxies.

Une raison spécifique pour laquelle j'ai utilisé Comlink était que je n'étais pas en mesure de transmettre des fonctions du thread principal au travailleur en utilisant du JavaScript simple. En utilisant le proxy de Comlink, j'ai pu facilement transmettre une fonction de rappel du thread principal au travailleur. [Référez-vous à cette rubrique]

Pour commencer à utiliser comlink dans votre projet, installez la bibliothèque

const worker = new Worker("./worker.js")

Pour commencer avec cette bibliothèque, nous devons connaître ces méthodes suivantes -

Comlink.wrap(point de terminaison)

  • Il enveloppe l'objet exposé du travailleur, renvoyant un proxy avec lequel vous pouvez interagir comme s'il s'agissait d'un objet local.
  • Le proxy aura toutes les propriétés et fonctions de la valeur exposée, mais l'accès et les invocations sont intrinsèquement asynchrones. c'est-à-dire que si une fonction renvoie un nombre, elle renverra désormais une promesse pour le nombre.
const worker = new Worker('./worker.js', { type: 'module' })

Comlink.expose(valeur, point final ?, autoriséOrigins ?)

  • La fonction exposer expose la valeur d'un thread à l'autre (c'est-à-dire exposer un objet du travailleur au thread principal)
worker.terminate() 

 

Comment vérifier si mon travailleur a été correctement enregistré ?

  • Pour vérifier si le fichier du travailleur a été enregistré dans le navigateur Web (j'utilise Chrome)
  • Faites un clic droit → Inspecter et accédez au panneau Sources où vous trouverez le fichier du travailleur.
  • Une fois terminé, le fichier du travailleur ne doit pas être visible dans le panneau Sources
  • Dans le cas où vous pouvez toujours voir le dossier du travailleur après avoir licencié le travailleur, il est probable que vous ayez enregistré plusieurs travailleurs et qu'ils n'aient pas tous été licenciés.

All you need to know about web workers to get started.

 


Lectures complémentaires
  • Gestionnaires de transfert et auditeurs d'événements
  • Travailleur partagé
  • Objets transférables



Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn