Web worker 란?

JavaScript는 싱글스레드 언어로, 모든 작업이 하나의 메인 스레드에서 실행됩니다. 하지만 Web Worker를 사용하면 별도의 스레드에서 코드를 실행할 수 있습니다. 이를 통해 무거운 연산이나 오래 걸리는 작업을 메인 스레드를 차단하지 않고 수행할 수 있어, UI의 반응성을 유지할 수 있습니다.
Web Worker는 DOM에 직접 접근할 수 없으며, 메인 스레드와 postMessage API를 통해 메시지를 주고받습니다.
notion image

장점

  • 메인 스레드 성능 유지: 메인 스레드와 별도로 동작을 하기 때문에 무거운 연산이나 시간이 오래 걸리는 작업으로 인한 UI 반응성을 저하시키지 않습니다. 이를 통해 앱의 성능과 사용자 경험을 개선 할 수 있습니다.
  • 비동기 처리: 웹 워커는 비동기로 실행되며, 메인스레드가 다른 작업을 처리하는 동안 워커에서는 연산 작업 진행합니다.
  • 복잡한 연산: 웹 워커는 무거운 연산을 백그라운드에서 처리 할 수 있어, 메인 스레드에서 발생할 수 있는 성능 병목을 피할 수 있습니다.

단점

  • DOM 접근 불가: 웹 워커는 메인 스레드에서 실행도는 브라우저의 DOM에 접근 할 수 없습니다. UI 업데이트는 반드시 메인 스레드를 통해 진행해야 됩니다. 워커는 UI 관련 작업을 직접 수행 할 수 없습니다.
  • 메모리 공유 제한: 웹 워커와 메인 스레드는 메모리를 공유하지 않습니다. 데이터를 주고 받기 위해서는 postMessage 를 사용해야 합니다. 데이터를 주고 받는 과정에서 데이터가 직렬화 되어야 하기 때문에 비용이 발생할 수 있으며 큰 데이터를 주고 받을 경우 성능 저하가 발생 할 수 있습니다.
  • 오버헤드: 웹 워커를 생성하는데 추가적인 리소스가 소모됩니다. 때문에 간단한 작업의 경우에는 워커를 생성하는 것 자체가 오버헤드가 될 수 있습니다.
  • 브라우저 제한: 브라우저 내에서 실행되는 것으로 브라우저 리소스 제한에 영향을 받을 수 있습니다. 워커를 너무 많이 생성할 경우 리소스 부족 문제가 발생할 수도 있습니다.

사용방법

  1. Web Worker 파일 생성: 백그라운드에서 실행될 코드를 별도의 파일로 작성합니다.
  1. 메인 스레드에서 Web Worker 생성: 메인 스레드에서 Web Worker를 생성하고, Worker에 메시지를 보내거나 Worker로부터 메시지를 받을 수 있습니다.
  1. 메시지 통신: postMessageonmessage 이벤트를 사용하여 메인 스레드와 Worker 간 통신을 수행합니다.
Service Worker와 다른점?
서비스 워커는 Web Worker의 한 종류입니다. 동일한 worker라는 점에서 window와 document 객체에 접근 할 수 없다는 점 그리고 제한된 브라우저 API를 사용 가능하다는 공통점이 있습니다. 하지만 네트워크 요청과 캐싱 같은 기능을 다루기 위한 용도로 설계되었습니다.
Service worker 출처와 경로에 대해 등록하는 이벤트 기반 워커로서 JavaScript 파일의 형태를 갖고 있습니다. 서비스 워커는 연관된 웹 페이지/사이트를 통제하여 탐색과 리소스 요청을 가로채 수정하고, 리소스를 굉장히 세부적으로 캐싱할 수 있습니다. 이를 통해 웹 앱이 어떤 상황에서 어떻게 동작해야 하는지 완벽하게 바꿀 수 있습니다. (제일 대표적인 상황은 네트워크를 사용하지 못할 때입니다.) - MDN 출처
특징
  • 비동기적: 서비스 워커는 비동기 API만 사용합니다. 이는 블로킹(blocking)을 방지하고, 백그라운드에서 효율적으로 작업을 처리할 수 있도록 합니다.
  • 독립적 실행: 서비스 워커는 웹 페이지의 컨텍스트에서 실행되지 않고, 자체 스코프에서 독립적으로 실행됩니다. 이는 페이지가 종료되어도 여전히 네트워크 요청을 가로채거나 푸시 알림을 처리할 수 있다는 의미입니다.
  • HTTPS 필요: 보안상의 이유로, 서비스 워커는 HTTPS 환경에서만 동작합니다. 단, 로컬호스트에서는 테스트 목적으로 예외적으로 허용됩니다.
라이프사이클
  • 등록(register):
    • 사용자가 페이지를 처음 방문하는것은 서비스워커가 없는 상태에서 이루어지게 되기 때문에 페이지가 완전히 로드될 때 까지 기다린 후에 등록하는 작업을 수행하게 됩니다.
    • 이렇게 하면 서비스워커가 무언가를 사전 캐시하는 경우 대역폭 경합을 방지 할 수 있습니다.
  • 설치(install):
    • 서비스워커는 처음으로 등록되면 install 이벤트가 발생하게 됩니다.
    • 개발자는 서비스워커가 사용할 리소스를 미리 캐싱 할 수 있습니다. 이를 통해 오프라인 상태에서도 앱을 정상적으로 작동 시킬 수 있습니다.
  • 대기(wait/activate):
    • 서비스워커가 설치되면 바로 활성화 되는 것이 아닌 대기(wait) 상태가 된다. 이전 서비스워커가 활성화 상태라면, 새 서비스워커는 그 작업이 끝날때 까지 대기(wait)해야 합니다.
    • activate 이벤트는 새로운 서비스워커가 활성화되면 발생하게 됩니다.
  • 동작(fetch):
    • 서비스워커가 활성화되면 fetch 이벤트를 사용하여 네트워크 요청을 가로채고 캐시에서 제공하거나 네트워크에서 직접 가져오는 등의 작업을 할 수 있습니다.

결론

Web Worker를 활용하면 JavaScript에서 부분적으로 멀티스레드를 구현할 수 있습니다(정통적인 멀티스레드와 차이가 있지만 말입니다). 많은 연산 혹은 시간이 많이 걸리는 작업에 대해서는 병렬적으로 처리 할 수 있어 UI에 영향을 주지 않도록 할 수 있습니다. 하지만 잘 못 사용하게 될 경우 성능에 문제를 줄 수 있기 때문에 사용시 주의를 기울여야합니다. 정말 필요한 경우에만 사용하게 된다면 정말 유용하지 않을까 싶습니다.
직접적으로 활용을 해보지는 않았지만, 개인적으로 한 번 적용 및 테스트를 해봐야겠습니다.
 

© 2024 dan.dev.log, All right reserved.

Built with NextJS