W poprzednim module omówiliśmy omówienie instancji roboczych. Pracownicy internetowe mogą poprawić reagowanie na dane wejściowe, przenosząc JavaScript z wątku głównego do osobne wątki dla usługi Web Worker, które mogą poprawić interakcję z witryną, następnego wyrenderowania (INP), jeśli masz pracę, która nie wymaga bezpośredniego dostępu do w wątku głównym. Samo omówienie nie wystarczy, a w tym module z konkretnym przypadkiem użycia dla pracownika internetowego.
Przykładem może być witryna, która musi usuwać metadane Exif z Nie jest to jednak nadmierna koncepcja. Witryny takie jak Flickr oferują przeglądać metadane Exif w celu uzyskania szczegółowych informacji technicznych dostępnych obrazów, takich jak głębia kolorów, marka i model aparatu i skalowalnych danych.
Jednak działanie logiczne przy pobieraniu obrazu, konwertowaniu go na ArrayBuffer
,
a wyodrębnianie metadanych Exif może być
kosztowne, jeśli w ogóle się to stanie.
w wątku głównym. Na szczęście zakres instancji internetowej pozwala na wykonywanie tych zadań.
niż w głównym wątku. Następnie, za pomocą potoku procesu komunikacyjnego instancji internetowej,
metadane Exif są przesyłane z powrotem do wątku głównego w postaci ciągu HTML,
wyświetlanych użytkownikowi.
Jak wygląda wątek główny bez rozszerzenia internetowego
Najpierw zobaczmy, jak wygląda główny wątek, gdy Web Worker. Aby to zrobić:
- Otwórz nową kartę w Chrome i otwórz jej Narzędzia deweloperskie.
- Otwórz panel skuteczności.
- Otwórz stronę https://exif-worker.glitch.me/without-worker.html.
- W panelu wyników kliknij Nagraj w prawym górnym rogu w panelu Narzędzia deweloperskie.
- Wklej ten link do zdjęcia lub inny dowolny link, który zawiera dane Exif metadanych – w tym polu kliknij przycisk Pobierz ten plik JPEG!.
- Gdy w interfejsie pojawią się metadane Exif, kliknij ponownie Record, aby Zatrzymaj nagrywanie.
Pamiętaj, że oprócz innych, które mogą być obecne, takich jak rasteryzator i tak dalej – wszystko w aplikacji dzieje się w wątku głównym. Na głównej stronie , zachodzą te procesy:
- Formularz przyjmuje dane wejściowe i wysyła żądanie
fetch
, aby uzyskać początkową wartość fragmentu zdjęcia zawierającego metadane Exif. - Dane obrazu są konwertowane na format
ArrayBuffer
. - Skrypt
exif-reader
służy do wyodrębniania metadanych Exif z biblioteki . - Dane te są pobierane do bazy danych w celu utworzenia ciągu HTML, który następnie wypełnia przeglądarki metadanych.
Przeciwieństwem jest wdrożenie takiego samego sposobu działania, ale robotnik!
Jak wygląda wątek główny z pracownikiem sieciowym
Wiesz już, jak wygląda wyodrębnianie metadanych Exif z JPEG w wątku głównym, zobacz, jak wygląda strona internetowa Proces ten obejmuje:
- Otwórz inną kartę w Chrome i otwórz jej Narzędzia deweloperskie.
- Otwórz panel skuteczności.
- Otwórz stronę https://exif-worker.glitch.me/with-worker.html.
- W panelu skuteczności kliknij przycisk nagrywania w prawym górnym rogu. w rogu panelu Narzędzia deweloperskie.
- Wklej ten link do zdjęcia w polu i kliknij przycisk Pobierz JPEG!.
- Gdy w interfejsie pojawią się metadane Exif, kliknij przycisk nagrywania. , aby zatrzymać nagrywanie.
To są możliwości rozwiązania Web Worker. Zamiast robić wszystko na stronie głównej w wątku, wszystko oprócz zapełniania przeglądarki metadanych kodem HTML odbywa się w osobnym wątku. Oznacza to, że wątek główny może zająć się czymś innym.
Być może największą zaletą jest to, że w przeciwieństwie do wersji
nie korzysta z instancji roboczej, skrypt exif-reader
nie jest wczytywany w głównym
na wątku, a nie na wątku Web Worker. Oznacza to, że koszt
pobieranie, analizowanie i kompilowanie skryptu exif-reader
odbywa się poza
w wątku głównym.
Teraz przyjrzymy się kodowi Web Worker, który to umożliwia.
Spojrzenie na kod Web Worker
Nie wystarczy samo zauważenie różnicy na rzecz kreatora witryn, zrozumieć, a przynajmniej w tym przypadku, jak wygląda ten kod, aby wiedzieć, w zakresie instancji roboczych.
Zacznij od kodu wątku głównego, który musi wystąpić, zanim instancja robocza będzie mogła wprowadź zdjęcie:
// 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';
});
Ten kod działa w wątku głównym i konfiguruje formularz do wysyłania adresu URL obrazu
z klientem w internecie. Potem kod Web Worker będzie się zaczynał od importScripts
instrukcja ładująca zewnętrzny skrypt exif-reader
, a następnie konfiguruje
z potokiem wiadomości do wątku głównego:
// 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);
});
});
Ten fragment kodu JavaScript konfiguruje potok komunikacji,
przesyła formularz z adresem URL pliku JPEG, adres URL dociera do instancji roboczej.
Kolejny fragment kodu wyodrębni metadane Exif z pliku JPEG.
tworzy ciąg HTML i wysyła go z powrotem do interfejsu window
,
wyświetlane użytkownikowi:
// 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('')
});
});
});
});
To dość obszerne, ale jest to również dość odpowiedni przypadek użycia przez pracowników WWW.
Jednak wyniki są warte swojej pracy, nie tylko w tym przypadku użycia.
Możesz używać pracowników internetowych do różnych zadań, np. do izolowania połączeń fetch
i przetwarzania odpowiedzi, przetwarzania dużych ilości danych bez blokowania
w wątku głównym – i to tylko na początek.
Poprawiając wydajność swoich aplikacji internetowych, zacznij myśleć o wszystko, co można zrobić rozsądnie w kontekście procesów internetowych. Zyski mogą być i może polepszyć wrażenia użytkowników witryny.