Przypadek użycia konkretnego narzędzia do pracy w sieci

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ć:

  1. Otwórz nową kartę w Chrome i otwórz jej Narzędzia deweloperskie.
  2. Otwórz panel skuteczności.
  3. Otwórz stronę https://exif-worker.glitch.me/without-worker.html.
  4. W panelu wyników kliknij Nagraj w prawym górnym rogu w panelu Narzędzia deweloperskie.
  5. 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!.
  6. Gdy w interfejsie pojawią się metadane Exif, kliknij ponownie Record, aby Zatrzymaj nagrywanie.
.
Narzędzie do profilowania wydajności pokazujące aktywność aplikacji wyodrębniającą metadane obrazu działającą w całości w wątku głównym. Wyróżniamy dwa bardzo długie zadania: jedno polega na pobieraniu żądanego obrazu i jego dekodowaniu, a drugie wyodrębnia metadane z obrazu.
. Aktywność głównego wątku w aplikacji wyodrębniania metadanych obrazu. Pamiętaj, że wszystkie aktywność ma miejsce w wątku głównym.

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:

  1. Formularz przyjmuje dane wejściowe i wysyła żądanie fetch, aby uzyskać początkową wartość fragmentu zdjęcia zawierającego metadane Exif.
  2. Dane obrazu są konwertowane na format ArrayBuffer.
  3. Skrypt exif-reader służy do wyodrębniania metadanych Exif z biblioteki .
  4. 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:

  1. Otwórz inną kartę w Chrome i otwórz jej Narzędzia deweloperskie.
  2. Otwórz panel skuteczności.
  3. Otwórz stronę https://exif-worker.glitch.me/with-worker.html.
  4. W panelu skuteczności kliknij przycisk nagrywania w prawym górnym rogu. w rogu panelu Narzędzia deweloperskie.
  5. Wklej ten link do zdjęcia w polu i kliknij przycisk Pobierz JPEG!.
  6. Gdy w interfejsie pojawią się metadane Exif, kliknij przycisk nagrywania. , aby zatrzymać nagrywanie.
.
Narzędzie do profilowania wydajności pokazujące aktywność aplikacji wyodrębniającą metadane obrazu, która występuje zarówno w wątku głównym, jak i w wątku instancji roboczej. Chociaż w wątku głównym nadal istnieją długie zadania, są one znacznie krótsze, a pobieranie/dekodowanie obrazu oraz wyodrębnianie metadanych odbywa się całkowicie w wątku instancji roboczej. Jedyna praca w wątku głównym obejmuje przekazywanie danych do i z instancji roboczej.
. Aktywność głównego wątku w aplikacji wyodrębniania metadanych obrazu. Należy pamiętać, że istnieje dodatkowy wątek, w którym wykonywana jest większość pracy.

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.