웹 작업자란 무엇입니까?

  • What are Web Workers?
  • Using Web Workers
  • Browser Support

  • 웹 작업자란 무엇입니까?



    웹 작업자는 백그라운드에서 실행되는 JavaScript 코드이며 페이지 성능에 영향을 미치지 않습니다.

    우리 모두 알다시피 JavaScript는 단일 스레드 언어이므로 한 번에 하나의 작업만 처리할 수 있습니다.

    예시

    let t = new Date();
    console.log(`tastk 1 took: ${new Date() - t}ms`);
    console.log(`tastk 2 took: ${new Date() - t}ms`);
    console.log(`tastk 3 took: ${new Date() - t}ms`);
    


    위의 예에서 콘솔에 다음과 같은 출력이 표시됩니다. In sequence just like we write.

    tastk 1 took: 0ms
    tastk 2 took: 0ms
    tastk 3 took: 1ms
    


    이러한 작업은 간단하기 때문에 콘솔을 열면 세 줄이 모두 인쇄되고 그 사이에 시간이 거의 없는 것을 볼 수 있습니다.

    하지만 작업 중 하나가 다른 작업보다 시간이 오래 걸린다면 어떻게 될까요?

    예시

    let t = new Date();
    console.log(`tastk 1 took: ${new Date() - t}ms`);
    console.log(`tastk 2 took: ${new Date() - t}ms`);
    let i = 0;
    while (i <= 10000000) {
      i++;
    }
    console.log(`tastk 3 took: ${new Date() - t}ms`);
    


    내 컴퓨터에서 인쇄하는 데 2777ms가 걸렸습니다task 3.

    tastk 1 took: 0ms
    tastk 2 took: 1ms
    tastk 3 took: 2777ms
    


    또 다른 예

    다음 코드를 복사하여 index.html 파일에 붙여넣거나 GitHub Repo을 다운로드합니다.

    index.html

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <title>Web Workers</title>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    
        <!-- counter -->
        <script>
          let i = 0;
          let intervalId = null;
          const counter = () => {
            if (!intervalId) {
              intervalId = setInterval(() => {
                i++;
                document.getElementById("counter").innerText = i;
              }, 300);
            } else {
              clearInterval(intervalId);
              i = 0;
              document.getElementById("counter").innerText = i;
              intervalId = null;
            }
          };
        </script>
    
        <!-- longCalculation -->
        <script>
          const longCalculation = () => {
            let i = 0;
            while (i <= 10000000000) {
              i++;
            }
            alert("Long calculation finished!");
          };
        </script>
      </head>
      <body>
        <h3>Counter: <span id="counter"> # </span></h3>
        <button onclick="counter()">Start Counter</button>
        <button onclick="longCalculation()">Long Calculation</button>
      </body>
    </html>
    


    첫 번째 버튼은 클릭하자마자 계산을 시작하는 간단한 카운터입니다.

    다른 버튼은 실행하는 데 오랜 시간이 걸리는 코드 조각입니다.

    클릭하면 계산이 완료될 때까지 나머지 페이지와 함께 카운터가 정지된 것을 볼 수 있습니다.



    The browser may also issue a warning, such as this page is slowing down your browser or this page is not responsive, or anything similar.



    JavaScript는 단일 스레드 언어이므로 계속하기 전에 계산이 완료될 때까지 기다려야 합니다.

    웹 작업자 사용



    여기에서 Web Workers가 도와드립니다.

    프로세스가 오랜 시간이 걸릴 가능성이 있는 경우 사용자는 프로세스가 완료될 때까지 기다릴 필요가 없습니다. 이것은 실제로 열악한 사용자 경험입니다.

    대신, 이러한 긴 작업은 백그라운드에서 수행되어야 합니다.

    다른 버튼을 만들어 보겠습니다Worker Calculation .

    <button onclick="workerCalculation()">Worker Calculation</button>
    


    이제 긴 계산의 논리를 별도의 파일에 추가합니다.

    worker.js

    let i = 0;
    while (i <= 1000000000) {
      i++;
    }
    postMessage("Worker calculation finished!");
    


    그리고 값을 직접 알려주는 대신 postMessage 방법을 사용하겠습니다.

    그리고 workerCalculation 함수의 논리는 다음과 같습니다.

    <script>
      const workerCalculation = () => {
        let worker = new Worker("worker.js");
        worker.onmessage = (e) => {
          alert(e.data);
        };
      };
    </script>
    


  • worker 인스턴스를 만듭니다.
  • 작업자의 경로를 포함합니다.
  • onmessage를 인수로 사용하는 event 콜백을 추가합니다
  • .

    이 콜백을 사용하여 계산이 완료되면 data 메서드에서 오는 postMessage를 경고합니다.



    이제 계산이 백그라운드에서 수행되며 페이지가 응답하지 않는 상태가 되지 않습니다.

    최종 index.html 파일

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <title>Web Workers</title>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    
        <!-- counter -->
        <script>
          let i = 0;
          let intervalId = null;
          const counter = () => {
            if (!intervalId) {
              intervalId = setInterval(() => {
                i++;
                document.getElementById("counter").innerText = i;
              }, 300);
            } else {
              clearInterval(intervalId);
              i = 0;
              document.getElementById("counter").innerText = i;
              intervalId = null;
            }
          };
        </script>
    
        <!-- longCalculation -->
        <script>
          const longCalculation = () => {
            let i = 0;
            while (i <= 10000000000) {
              i++;
            }
            alert("Long calculation finished!");
          };
        </script>
    
        <!-- workerCalculation -->
        <script>
          const workerCalculation = () => {
            let worker = new Worker("worker.js");
            worker.onmessage = (e) => {
              alert(e.data);
            };
          };
        </script>
      </head>
      <body>
        <h3>Counter: <span id="counter"> # </span></h3>
    
        <button onclick="counter()">Start Counter</button>
        <button onclick="longCalculation()">Long Calculation</button>
        <button onclick="workerCalculation()">Worker Calculation</button>
      </body>
    </html>
    


    브라우저 지원



    웹 작업자는 모든 브라우저에서 지원되지 않습니다.

    웹 워커를 만들기 전에 사용자의 브라우저가 웹 워커를 지원하는지 확인해야 합니다.

    if (typeof Worker !== "undefined") {
      // Yes!
    } else {
      // No!
    }
    


    따라서 worker.js 파일은 다음과 같아야 합니다.

    if (typeof Worker !== "undefined") {
      let i = 0;
      while (i <= 1000000000) {
        i++;
      }
      postMessage("Worker calculation finished!");
    } else {
      alert("Your browser doesn't support web workers.");
    }
    


    Learn more about Web Workers API

    좋은 웹페이지 즐겨찾기