구체적인 웹 작업자 사용 사례

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

마지막 모듈에서는 웹 작업자에 관한 개요가 제공되었습니다. 웹 작업자는 JavaScript를 기본 스레드에서 다른 곳으로 이동하여 입력 응답성을 개선 웹 작업자 스레드를 분리하여 웹사이트 상호작용 INP (다음 페인트)에 추가할 수 있습니다. 기본 스레드로 이동합니다. 개요만으로는 충분하지 않습니다. 이 모듈에서는 구체적인 사용 사례가 제공됩니다.

이러한 사용 사례로는 웹사이트에서 Exif 메타데이터를 이는 당연한 개념이 아닙니다. 실제로 Flickr 같은 웹사이트는 Exif 메타데이터로 볼 수 있어 API에 대한 기술적 세부 정보를 알 수 이미지(예: 색심도, 카메라 제조업체 및 모델) 데이터를 수집하는 데 사용됩니다

그러나 이미지를 가져와 ArrayBuffer로 변환하는 로직은 Exif 메타데이터를 추출하는 작업은 확인할 수 있습니다. 다행히 웹 작업자 범위를 사용하면 기본 스레드를 벗어납니다. 그런 다음 웹 작업자의 메시징 파이프라인을 사용하여 Exif 메타데이터가 HTML 문자열로 기본 스레드에 다시 전송됩니다. 사용자에게 표시됩니다.

웹 작업자가 없는 기본 스레드의 모습

먼저 있습니다 이렇게 하려면 다음 단계를 따르세요.

  1. Chrome에서 새 탭을 열고 DevTools를 엽니다.
  2. 성능 패널을 엽니다.
  3. https://exif-worker.glitch.me/without-worker.html로 이동합니다.
  4. 성능 패널에서 오른쪽 상단에 있는 Record를 클릭합니다. 나타납니다.
  5. 이 이미지 링크 또는 Exif가 포함된 다른 링크를 붙여넣습니다. 메타데이터 파일을 선택하고 Get that JPEG! 버튼을 클릭합니다.
  6. 인터페이스가 Exif 메타데이터로 채워지면 Record를 다시 클릭하여 녹음을 중지합니다.
를 통해 개인정보처리방침을 정의할 수 있습니다. <ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">전적으로 기본 스레드에서 발생하는 이미지 메타데이터 추출기 앱의 활동을 보여주는 성능 프로파일러 여기에는 두 가지 긴 작업이 있습니다. 하나는 가져오기를 실행하여 요청된 이미지를 가져와 디코딩하는 작업이고 다른 하나는 이미지에서 메타데이터를 추출하는 작업입니다.</ph> <ph type="x-smartling-placeholder">
</ph> 이미지 메타데이터 추출기 앱의 기본 스레드 활동 모든 활동이 기본 스레드에서 발생합니다.

있을 수 있는 다른 스레드(예: 래스터라이저)는 제외하고 등의 작업을 수행합니다. 앱의 모든 작업은 기본 스레드에서 발생합니다. 기본 스레드가 발생하면 다음과 같은 상황이 발생합니다.

  1. 양식은 입력을 받고 fetch 요청을 전달하여 초기 URL을 가져옵니다. 부분(예: EXIF 메타데이터가 포함된 이미지의 일부)을 캡처합니다.
  2. 이미지 데이터는 ArrayBuffer로 변환됩니다.
  3. exif-reader 스크립트는 이미지
  4. 메타데이터를 스크랩하여 HTML 문자열을 구성한 다음 메타데이터 뷰어입니다.

이제 동일한 동작을 구현하지만 근로자!

웹 작업자가 있는 기본 스레드의 모습

지금까지 이미지에서 Exif 메타데이터를 추출하는 과정을 살펴보았습니다. JPEG 파일이 있다면 웹에서 다음과 같은 경우

  1. Chrome에서 다른 탭을 열고 DevTools를 엽니다.
  2. 성능 패널을 엽니다.
  3. https://exif-worker.glitch.me/with-worker.html로 이동합니다.
  4. 공연 패널에서 오른쪽 상단에 있는 녹화 버튼을 클릭합니다. 나타납니다.
  5. 입력란에 This image link를 붙여넣고 Get that JPEG! 버튼을 클릭합니다.
  6. 인터페이스가 Exif 메타데이터로 채워지면 기록 버튼을 클릭합니다. 을 눌러 녹화를 중지합니다.
를 통해 개인정보처리방침을 정의할 수 있습니다. <ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">기본 스레드와 웹 작업자 스레드에서 모두 발생하는 이미지 메타데이터 추출기 앱의 활동을 보여주는 성능 프로파일러 기본 스레드에는 여전히 긴 작업이 있지만 이미지 가져오기/디코딩 및 메타데이터 추출이 전적으로 웹 작업자 스레드에서 발생하므로 작업은 상당히 짧습니다. 유일한 기본 스레드 작업은 웹 작업자와 데이터를 주고받는 것입니다.</ph> <ph type="x-smartling-placeholder">
</ph> 이미지 메타데이터 추출기 앱의 기본 스레드 활동 참고: 추가 웹 워커 스레드를 생성할 수 있습니다.

이는 웹 작업자의 힘입니다. 기본 설정에서 모든 작업을 HTML로 메타데이터 뷰어 채우기를 제외한 모든 작업은 별도의 스레드가 필요합니다. 즉, 기본 스레드가 해제되어 다른 작업을 할 수 있습니다.

아마도 가장 큰 장점은 앞서 얘기한 이 앱의 버전과는 달리 웹 워커를 사용하지 않으면 exif-reader 스크립트가 기본 스레드가 아니고 웹 작업자 스레드에 있습니다. 다시 말해 exif-reader 스크립트 다운로드, 파싱, 컴파일은 기본 스레드로 이동합니다.

이제 이 모든 작업을 가능하게 하는 웹 작업자 코드를 살펴보겠습니다.

웹 작업자 코드 살펴보기

웹 작업자가 만들어내는 차이를 보는 것만으로는 충분하지 않지만 이 경우에는 코드가 어떤 모양인지를 이해할 수 있기 때문에 가능한 한 많이 있습니다

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

웹 작업자가 작업을 수행하기 전에 발생해야 하는 기본 스레드 코드로 시작합니다. 사진 입력:

// 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';
});

이 코드는 기본 스레드에서 실행되고 이미지 URL을 전송할 양식을 설정합니다. 웹 작업자의 몫입니다 여기에서 웹 작업자 코드는 importScripts 문을 연 다음 외부 exif-reader 스크립트를 로드한 다음 메시지 파이프라인을 기본 스레드에 전달합니다.

// 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">

이 JavaScript는 사용자가 메시지를 보낼 때 URL이 있는 양식을 JPEG 파일에 제출하면 URL이 웹 워커에 도착합니다. 거기에서 다음 비트 코드는 JPEG 파일에서 Exif 메타데이터를 추출합니다. HTML 문자열을 빌드하고 이 HTML을 window로 다시 보내어 최종적으로 사용자에게 표시됩니다.

// 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('')
      });
    });
  });
});

다소 읽기는 어렵지만 웹 작업자의 경우 상당히 관련 있는 사용 사례이기도 합니다. 그러나 결과는 이 사용 사례에만 국한되지 않고 노력할 가치가 있습니다. fetch 호출 격리와 같은 모든 종류의 작업에 웹 작업자를 사용할 수 있습니다. 대량의 데이터를 처리하고 이는 시작에 불과합니다.

웹 애플리케이션의 성능을 개선할 때는 웹 작업자 컨텍스트에서 합리적으로 수행할 수 있는 모든 것입니다. 이점은 웹사이트의 사용자 환경을 전반적으로 개선할 수 있습니다.