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 :
- Ouvrez un nouvel onglet dans Chrome, puis les outils de développement associés.
- Ouvrez le panneau des performances.
- Accédez à https://exif-worker.glitch.me/without-worker.html.
- Dans le panneau des performances, cliquez sur Record (Enregistrer) en haut à droite de le volet DevTools.
- 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 !).
- 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.
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:
- 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. - Les données de l'image sont converties en
ArrayBuffer
. - Le script
exif-reader
permet d'extraire les métadonnées Exif du l'image. - 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é:
- Ouvrez un autre onglet dans Chrome, puis ouvrez les outils de développement associés.
- Ouvrez le panneau des performances.
- Accédez à https://exif-worker.glitch.me/with-worker.html.
- Dans le panneau des performances, cliquez sur le bouton d'enregistrement en haut à droite. dans l'angle supérieur droit du volet "DevTools".
- Collez le lien de cette image dans le champ, puis cliquez sur le bouton Get this JPEG! (Obtenir ce fichier JPEG !).
- 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.
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);
});
});
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.