Im letzten Modul haben wir einen Überblick über Web Worker erhalten. Web Worker können die Eingabereaktionsfähigkeit verbessern, indem JavaScript aus dem Hauptthread separate Web Worker-Threads, wodurch Sie die Interaktion der Nutzer mit Ihrer Website verbessern können. auf Next Paint (INP) umstellen, wenn Ihre Arbeit keinen direkten Zugriff auf das im Hauptthread. Eine Übersicht allein reicht jedoch nicht aus. wird ein konkreter Anwendungsfall für einen Web Worker angeboten.
Ein Beispiel hierfür wäre eine Website, die EXIF-Metadaten aus einer ist kein so weit hergeholtes Konzept. Websites wie Flickr bieten sogar können Nutzer die EXIF-Metadaten aufrufen, um technische Details zur wie Farbtiefe, Marke und Modell der Kamera Daten.
Die Logik zum Abrufen eines Bildes und seiner Konvertierung in ein ArrayBuffer
-Element jedoch
Das Extrahieren der EXIF-Metadaten könnte teuer sein,
im Hauptthread. Glücklicherweise ermöglicht der Web Worker-Bereich
aus dem Hauptthread entfernt. Mithilfe der Messaging-Pipeline des Web Workers
EXIF-Metadaten werden als HTML-String an den Hauptthread zurückgesendet und
die der Nutzer sieht.
So sieht der Hauptthread ohne Web Worker aus
Sehen Sie sich zunächst an, wie der Hauptthread aussieht, wenn wir das ohne Web Worker. Führen Sie dazu die folgenden Schritte aus:
- Öffne einen neuen Tab in Chrome und öffne die zugehörigen Entwicklertools.
- Öffnen Sie den Bereich „Leistung“.
- Rufen Sie https://exif-worker.glitch.me/without-worker.html auf.
- Klicken Sie im Bereich „Leistung“ rechts oben im Entwicklertools-Bereich.
- Fügen Sie diesen Bildlink ein oder einen anderen Ihrer Wahl, der die EXIF-Datei enthält. Metadaten – in das Feld und klicken Sie auf die Schaltfläche JPEG herunterladen!.
- Sobald die EXIF-Metadaten in die Schnittstelle aufgenommen wurden, klicken Sie noch einmal auf Record (Aufzeichnen). Aufzeichnung beenden.
Beachten Sie, dass neben anderen Threads, die möglicherweise vorhanden sind, wie z. B. Rasterizer, und so weiter: In der App findet alles im Hauptthread statt. Auf der Hauptseite passiert Folgendes:
- Das Formular nimmt die Eingabe entgegen und sendet eine
fetch
-Anfrage, um die ursprüngliche des Bilds, das die EXIF-Metadaten enthält. - Die Bilddaten werden in ein
ArrayBuffer
konvertiert. - Das Skript
exif-reader
wird verwendet, um die EXIF-Metadaten aus der Bild. - Die Metadaten werden extrahiert, um einen HTML-String zu erstellen, der dann das Feld Metadaten-Viewer.
Dies lässt sich mit einer Implementierung desselben Verhaltens vergleichen, Arbeiter!
So sieht der Hauptthread mit einem Web Worker aus
Jetzt wissen Sie, wie das Extrahieren der EXIF-Metadaten aus einem JPEG-Datei im Hauptthread an. Worker enthalten ist:
- Öffnen Sie einen weiteren Tab in Chrome und dann die zugehörigen Entwicklertools.
- Öffnen Sie den Bereich „Leistung“.
- Rufen Sie https://exif-worker.glitch.me/with-worker.html auf.
- Klicken Sie rechts oben im Leistungsbereich auf die Schaltfläche zum Aufzeichnen. des Bereichs „Entwicklertools“ aus.
- Fügen Sie diesen Bildlink in das Feld ein und klicken Sie auf die Schaltfläche JPEG herunterladen!.
- Sobald die EXIF-Metadaten auf der Oberfläche angezeigt werden, klicken Sie auf die Schaltfläche Aufzeichnen. noch einmal, um die Aufzeichnung zu beenden.
Dies ist die Leistungsfähigkeit eines Web Workers. Anstatt alle Hauptaufgaben Alles außer dem Befüllen des Metadaten-Viewers mit HTML erfolgt auf einer separaten Thread. Das bedeutet, dass der Hauptthread für andere Aufgaben freigegeben wird.
Der vielleicht größte Vorteil dieser App besteht darin,
keinen Web Worker verwendet, wird das Skript exif-reader
nicht auf der
sondern im Web Worker-Thread. Das bedeutet, dass die Kosten
Das Herunterladen, Parsen und Kompilieren des exif-reader
-Skripts erfolgt außerhalb des
im Hauptthread.
Sehen wir uns nun den Web Worker-Code genauer an, der dies ermöglicht.
Ein Blick auf den Web Worker-Code
Es reicht nicht aus, den Unterschied eines Web Workers zu sehen. Es hilft auch, um zu verstehen, wie dieser Code aussieht, um zu wissen, Web Worker-Bereich möglich.
<ph type="x-smartling-placeholder">Beginnen Sie mit dem Code des Hauptthreads, der erstellt werden muss, bevor der Web Worker kann Bild eingeben:
// 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';
});
Dieser Code wird im Hauptthread ausgeführt und richtet das Formular zum Senden der Bild-URL an
Web Worker. Von dort beginnt der Web Worker-Code mit dem Präfix importScripts
.
-Anweisung, die das externe exif-reader
-Skript lädt und dann das
Messaging-Pipeline zum Hauptthread:
// 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);
});
});
Dieser JavaScript-Code richtet die Messaging-Pipeline ein, sodass Nutzer, die
das Formular mit einer URL an eine JPEG-Datei sendet, kommt die URL im Web Worker an.
Von dort extrahiert dieser nächste Code-Snippet die EXIF-Metadaten aus der JPEG-Datei,
erstellt einen HTML-String und sendet diesen HTML-Code zurück an die window
, damit er schließlich
angezeigt:
// 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('')
});
});
});
});
Es ist ein wenig zu lesen, aber dies ist auch ein ziemlich verwickelter Anwendungsfall für Web Worker.
Die Ergebnisse sind jedoch die Arbeit wert und nicht nur auf diesen Anwendungsfall beschränkt.
Sie können Web Worker für verschiedenste Zwecke verwenden, z. B. zum Isolieren von fetch
-Aufrufen
und Antworten verarbeiten und große Datenmengen verarbeiten, ohne
Hauptthread – und das ist nur für den Anfang.
Wenn Sie die Leistung Ihrer Webanwendungen verbessern, sollten Sie alles, was in einem Web Worker-Kontext vernünftigerweise möglich ist. Die Gewinne könnten und können zu einer insgesamt besseren Nutzererfahrung auf Ihrer Website führen.