Un cas d'utilisation concret d'un travailleur Web

<ph type="x-smartling-placeholder">

Dans le dernier module, nous vous avons donné une présentation des nœuds de calcul Web. Les nœuds de calcul Web peuvent améliorer la réactivité aux entrées en déplaçant le code JavaScript du thread principal vers des threads de travail Web distincts, ce qui peut vous aider à améliorer l'interaction à Next Paint (INP) lorsque votre travail n'a pas besoin d'un accès direct thread principal. Cependant, un aperçu ne suffit pas. Dans ce module, est proposée pour un cas d'utilisation concret d'un travailleur Web.

Par exemple, un site Web qui doit supprimer les métadonnées Exif d'un ce concept n'est pas si farfelu. D'ailleurs, des sites Web tels que Flickr proposent aux utilisateurs un moyen d'afficher les métadonnées Exif afin d'obtenir des détails techniques sur les les images qu'ils hébergent, comme la profondeur de couleur, la marque et le modèle de l'appareil photo, données.

Cependant, la logique permettant d'extraire une image et de la convertir en ArrayBuffer et l'extraction des métadonnées Exif pourrait être potentiellement coûteuse si elle était effectuée entièrement sur le thread principal. Heureusement, le champ d'application du nœud de calcul Web permet d'effectuer ce travail en dehors du thread principal. Ensuite, à l'aide du pipeline de messagerie du nœud de calcul Web, Les métadonnées EXIF sont transmises au thread principal sous forme de chaîne HTML, et visibles par l'utilisateur.

À quoi ressemble le thread principal sans nœud de calcul Web ?

Tout d'abord, observez à quoi ressemble le thread principal lorsque nous effectuons cette tâche sans Web Worker. Pour ce faire, procédez comme suit :

  1. Ouvrez un nouvel onglet dans Chrome, puis les outils de développement associés.
  2. Ouvrez le panneau des performances.
  3. Accédez à https://exif-worker.glitch.me/without-worker.html.
  4. Dans le panneau des performances, cliquez sur Record (Enregistrer) en haut à droite de le volet DevTools.
  5. Collez ce lien image ou un autre de votre choix contenant Exif métadonnées) dans le champ, puis cliquez sur le bouton Get this JPEG! (Obtenir ce fichier JPEG !).
  6. Une fois que les métadonnées Exif sont insérées dans l'interface, cliquez à nouveau sur Record (Enregistrer) pour arrêter l'enregistrement.
<ph type="x-smartling-placeholder">
</ph> Profileur de performances affichant l&#39;activité de l&#39;application d&#39;extraction des métadonnées d&#39;image qui se produit entièrement sur le thread principal. Il existe deux grandes tâches longues : l&#39;une qui exécute une extraction pour obtenir l&#39;image demandée et la décode, et l&#39;autre qui extrait les métadonnées de l&#39;image. <ph type="x-smartling-placeholder">
</ph> Activité du thread principal dans l'application d'extraction de métadonnées d'image. Notez que tous l'activité a lieu sur le thread principal.

Hormis les autres fils éventuellement présents, comme le rastériseur les threads, etc., tout ce qui se trouve dans l'application se produit sur le thread principal. Sur la page principale ce qui se produit:

  1. Le formulaire reçoit l'entrée et envoie une requête fetch pour obtenir l'adresse de l'image contenant les métadonnées Exif.
  2. Les données de l'image sont converties en ArrayBuffer.
  3. Le script exif-reader permet d'extraire les métadonnées Exif du l'image.
  4. Les métadonnées sont extraites pour construire une chaîne HTML, qui renseigne ensuite le lecteur de métadonnées.

Par contraste, avec une implémentation du même comportement, mais en utilisant un navigateur ou d'un nœud de calcul !

À quoi ressemble le thread principal avec un nœud de calcul Web

Maintenant que vous savez à quoi ressemble l'extraction des métadonnées Exif à partir d'une JPEG sur le thread principal, regardez ce à quoi cela ressemble et que le nœud de calcul n'est pas intégré:

  1. Ouvrez un autre onglet dans Chrome, puis ouvrez les outils de développement associés.
  2. Ouvrez le panneau des performances.
  3. Accédez à https://exif-worker.glitch.me/with-worker.html.
  4. Dans le panneau des performances, cliquez sur le bouton d'enregistrement en haut à droite. dans l'angle supérieur droit du volet "DevTools".
  5. Collez le lien de cette image dans le champ, puis cliquez sur le bouton Get this JPEG! (Obtenir ce fichier JPEG !).
  6. Une fois que les métadonnées Exif sont insérées dans l'interface, cliquez sur le bouton d'enregistrement. pour arrêter l'enregistrement.
<ph type="x-smartling-placeholder">
</ph> Profileur de performances affichant l&#39;activité de l&#39;application d&#39;extraction de métadonnées d&#39;image qui se produit à la fois sur le thread principal et sur un thread de nœud de calcul Web. Bien qu&#39;il y ait encore de longues tâches sur le thread principal, elles sont nettement plus courtes, car la récupération/le décodage d&#39;images et l&#39;extraction des métadonnées se font entièrement sur un thread de travail Web. La seule tâche du thread principal consiste à transmettre des données vers et depuis le nœud de calcul Web. <ph type="x-smartling-placeholder">
</ph> Activité du thread principal dans l'application d'extraction de métadonnées d'image. Notez qu'il existe un thread de travail Web supplémentaire où la majeure partie du travail est effectuée.

C'est toute la puissance d'un travailleur Web. Au lieu de tout faire sur la , à l'exception du chargement HTML de la visionneuse de métadonnées, thread distinct. Cela signifie que le thread principal est libéré pour effectuer d'autres tâches.

Le principal avantage est que, contrairement à la version de cette application, n'utilise pas de nœud de calcul Web, le script exif-reader n'est pas chargé sur le mais plutôt sur celui du nœud de calcul Web. Cela signifie que le coût le téléchargement, l'analyse et la compilation du script exif-reader ont lieu thread principal.

Penchons-nous à présent sur le code du travailleur Web qui rend tout cela possible.

À propos du code d'un nœud de calcul Web

Montrer l'intérêt d'un travailleur Web ne suffit pas. comprendre, du moins dans ce cas, à quoi ressemble ce code afin que vous sachiez à quoi possible dans le champ d'application d'un nœud de calcul Web.

<ph type="x-smartling-placeholder">

Commencez par le code du thread principal qui doit apparaître avant que le nœud de calcul Web puisse saisissez l'image:

// scripts.js

// Register the Exif reader web worker:
const exifWorker = new Worker('/js/with-worker/exif-worker.js');

// We have to send image requests through this proxy due to CORS limitations:
const imageFetchPrefix = 'https://res.cloudinary.com/demo/image/fetch/';

// Necessary elements we need to select:
const imageFetchPanel = document.getElementById('image-fetch');
const imageExifDataPanel = document.getElementById('image-exif-data');
const exifDataPanel = document.getElementById('exif-data');
const imageInput = document.getElementById('image-url');

// What to do when the form is submitted.
document.getElementById('image-form').addEventListener('submit', event => {
  // Don't let the form submit by default:
  event.preventDefault();

  // Send the image URL to the web worker on submit:
  exifWorker.postMessage(`${imageFetchPrefix}${imageInput.value}`);
});

// This listens for the Exif metadata to come back from the web worker:
exifWorker.addEventListener('message', ({ data }) => {
  // This populates the Exif metadata viewer:
  exifDataPanel.innerHTML = data.message;
  imageFetchPanel.style.display = 'none';
  imageExifDataPanel.style.display = 'block';
});

Ce code s'exécute sur le thread principal et configure le formulaire pour envoyer l'URL de l'image à le nœud de calcul Web. À partir de là, le code d'un nœud de calcul Web commence par un importScripts qui charge le script exif-reader externe, puis configure la de messagerie vers le thread principal:

// exif-worker.js

// Import the exif-reader script:
importScripts('/js/with-worker/exifreader.js');

// Set up a messaging pipeline to send the Exif data to the `window`:
self.addEventListener('message', ({ data }) => {
  getExifDataFromImage(data).then(status => {
    self.postMessage(status);
  });
});
<ph type="x-smartling-placeholder">

Ce bit de JavaScript configure le pipeline de messagerie de sorte que lorsque l'utilisateur envoie le formulaire avec une URL pointant vers un fichier JPEG, l'URL arrive au nœud de calcul Web. À partir de là, le morceau de code suivant extrait les métadonnées Exif du fichier JPEG, crée une chaîne HTML et la renvoie à window pour être visible par l'utilisateur:

// Takes a blob to transform the image data into an `ArrayBuffer`:
// NOTE: these promises are simplified for readability, and don't include
// rejections on failures. Check out the complete web worker code:
// https://glitch.com/edit/#!/exif-worker?path=js%2Fwith-worker%2Fexif-worker.js%3A10%3A5
const readBlobAsArrayBuffer = blob => new Promise(resolve => {
  const reader = new FileReader();

  reader.onload = () => {
    resolve(reader.result);
  };

  reader.readAsArrayBuffer(blob);
});

// Takes the Exif metadata and converts it to a markup string to
// display in the Exif metadata viewer in the DOM:
const exifToMarkup = exif => Object.entries(exif).map(([exifNode, exifData]) => {
  return `
    <details>
      <summary>
        <h2>${exifNode}</h2>
      </summary>
      <p>${exifNode === 'base64' ? `<img src="data:image/jpeg;base64,${exifData}">` : typeof exifData.value === 'undefined' ? exifData : exifData.description || exifData.value}</p>
    </details>
  `;
}).join('');

// Fetches a partial image and gets its Exif data
const getExifDataFromImage = imageUrl => new Promise(resolve => {
  fetch(imageUrl, {
    headers: {
      // Use a range request to only download the first 64 KiB of an image.
      // This ensures bandwidth isn't wasted by downloading what may be a huge
      // JPEG file when all that's needed is the metadata.
      'Range': `bytes=0-${2 ** 10 * 64}`
    }
  }).then(response => {
    if (response.ok) {
      return response.clone().blob();
    }
  }).then(responseBlob => {
    readBlobAsArrayBuffer(responseBlob).then(arrayBuffer => {
      const tags = ExifReader.load(arrayBuffer, {
        expanded: true
      });

      resolve({
        status: true,
        message: Object.values(tags).map(tag => exifToMarkup(tag)).join('')
      });
    });
  });
});

C'est un peu à lire, mais il s'agit également d'un cas d'utilisation assez complexe pour les nœuds de calcul Web. Toutefois, les résultats en valent la peine, et pas seulement pour ce cas d'utilisation. Vous pouvez utiliser des nœuds de calcul Web pour toutes sortes de choses, comme isoler les appels fetch. ainsi que le traitement des réponses et de grandes quantités de données sans bloquer thread principal, et ce n'est qu'un début.

Lorsque vous améliorez les performances de vos applications Web, tout ce qui peut raisonnablement être fait dans un contexte de nœud de calcul Web. Les gains pourraient être est significative et peut contribuer à améliorer l'expérience utilisateur globale de votre site Web.