-
웹 워커(Web Worker)CS 2024. 9. 24. 12:31
사실 거의 처음 들어보는 것과 다름 없었던 개념이었던 Web Worker.
기본적으로 큰 틀은 알겠어도, 각각의 자료마다 설명하고자 하는 내용이 달랐던 부분이 많았다.
그래서 이해하는 데까지 많은 시간이 소요된 글 중 하나이다.
❓Web Workers❓
Web Workers는 스크립트 연산을 웹 애플리케이션의 주 실행 스레드와 분리된 별도의 백그라운드 스레드에서 실행할 수 있는 기술이다.
이 기능을 통해 웹 애플리케이션은 사용자 인터페이스(UI)를 차단하지 않고도 복잡한 연산을 수행할 수 있다.
특히, 무거운 작업을 분리된 스레드에서 처리하면서 스레드가 멈추거나 느려지는 현상을 방지할 수 있다.
📌 Web Worker 개념 📌
웹 워커를 생성할 때는 Worker() 등의 생성자로 생성한다.
웹 워커에서 실행되는 코드는 일반적으로 JS와 코드와 같다. 그래서 원하는 코드는 뭐든 워커 스레드에서 실행할 수 있으나, 워커에서 DOM을 직접 조작할 수 없고, window의 일부 메서드와 속성은 사용할 수 없다.
다만, webSocket과 indexedDB 같은 일부 API에서는 사용이 가능하다.
💡 [헷갈릴 수 있는 개념] Web Worker와 Web Worker API 💡
Web Worker
: 브라우저 환경에서 독립적으로 자바스크립트 코드를 실행할 수 있는 기능이다. 이를 통해 비동기 작업을 처리할 수 있다.
Web Worker API
: 웹 워커를 생성하고 관리하는 데 사용되는 프로그래밍 인터페이스로, 워커의 생성, 메시지 송수신 등을 가능하게 한다.🤔 왜 Web Workers를 사용하는가? 🤔
자바스크립트는 기본적으로 싱글 스레드로 작동한다는 것을 JS를 조사해본 사람들이라면 알 수 있다.
모른다면, 먼저 이 개념을 아는 것이 중요할 거 같다.
싱글 스레드는 작업량이 많을 경우 작업이 완료되어야 다음 작업을 수행할 수 있는데, 이로 인해 대량의 작업이 처리될 때 UI가 멈추거나 느려질 수 있다.
예를 들어, 갑자기 웹 페이지를 스크롤하던 중 무거운 연산이 수행되어, 브라우저가 다운되거나 느려지는 응답성이 떨어진 UI를 경험하게 되는 것을 대표적인 예로 볼 수 있다.
또 다른 예로는 브라우저 탭이 비활성화될 경우 크롬에서는 시간이 멈추고, 사파리에서는 시간이 1.5배속으로 흐르는 등의 현상이 발생하는 것 등을 예로 들 수 있다.
이러한 문제를 해결하기 위해 Web Workers를 사용하게 되는데, 웹 워커는 메인 스레드와는 별도로 실행되므로 브라우저가 비활성화되어 있는 상태인 것에 영향을 받지 않는 상태에서 멀티 스레딩의 장점을 취할 수 있다. 또한, 쓰로틀링 문제도 해결할 수 있으며, 브라우저가 비활성화된 탭에서 발생하는 이벤트에 대해 딜레이를 주거나 무시하는 현상도 피할 수 있다.
💡 [참고] 쓰로틀링 💡
: 브라우저가 비활성화된 탭에서 반복적으로 발생하는 이벤트에 딜레이를 주거나 이벤트를 무시하여 메모리를 효율적으로 관리하는 방식이다. 반복적인 작업을 수행할 때 이 문제가 발생할 수 있다.🤔 웹 워커와 메인 스레드는 어떻게 통신하는가? 🤔
워커와 메인 스레드 간의 데이터 교환은 메시지 시스템을 사용한다.
이 메시지 시스템이라는 게 어떻게 보면 socket 통신 같이도 느껴지기도 했다.
이 메시지 시스템이 어떤 것인지를 보면,
양측 모두 postMessage() 메서드를 통해 데이터를 전송하며,
onmessage 이벤트는 수신한 메시지의 data 속성을 통해 이를 처리한다.
🚨 이때 전송되는 데이터는 복사되며, 공유되지 않는다. 🚨
이를 통해서 데이터의 무결성을 보장하고, 동기화 문제를 피할 수 있다.
⚠️ Web Workers 도입 시 주의사항 ⚠️
어떻게 보면 Web Worker를 도입하는 것은 장점만 존재한다고 느껴질 거 같다.
하지만 Web Workers의 장단점이 뚜렷하므로, 정말 필요한 경우에만 사용하는 것이 좋다.
대표적으로 단순한 작업에는 굳이 Web Workers를 도입할 필요가 없다.
멀티 스레드를 사용하게 되면 컨텍스트 스위칭이 잦아지면서 오버헤드 비용이 발생할 수 있으며, 이로 인해 성능 저하 문제가 생길 수 있다.
그렇기에, 사용하기 전에 정말 필요한지를 잘 판단하여 사용해야 한다.
하지만 이렇게 말해도 이제 어떨 때 사용해야할지 감이 안 올 수 있으니, 어떤 경우에 사용하는 것이 좋은지 보도록 하자.
❌ 사용하지 않는 경우 ❌
대부분의 데이터 처리는 서버에서 이루어지기 때문에 Web Workers를 굳이 사용할 필요가 없다.
일반적으로 웹 애플리케이션에서 부하가 걸리는 작업을 잘 하지 않으며, DOM 제어 및 window 객체의 일부 함수는 메인 스레드에서만 가능하다.
위에서 언급했듯이, 단순한 계산식에서는 Web Workers를 사용하는 것이 오히려 비효율적일 수 있으며, 메인 스레드와 워커의 메시지 수신 과정에서 비용이 발생할 수 있다.
⭕️ 사용하는 경우 ⭕️
유용한 경우는 다음과 같다.
- 화면 동작에 영향을 미치는 연산 작업인 바이너리 파일 핸들링이나 복잡한 계산이 필요한 경우
- 메인 스레드에 영향을 미치지 않고 백그라운드에서 작업을 지속적으로 수행할 때
- 싱글 페이지 애플리케이션(SPA)에서 사용자 경험을 개선하고 응답성을 유지할 필요가 있을 때
🤔 웹 워커를 활용한 멀티 스레드의 문제와 SharedArrayBuffer 🤔
각 웹 워커는 독립적인 단위로 작동하기 때문에, 자원 공유가 어렵다.
자바스크립트는 기본적으로 스레드 간 메모리를 공유하는 방법을 제공하지 않지만, ArrayBuffer를 통해 일부 메모리를 공유할 수 있다.
이를 해결하는 방법이 바로 SharedArrayBuffer로, 이를 통해 여러 스레드 간의 메모리 공유가 가능해진다.
SharedArrayBuffer를 사용하면 스레드 간 데이터의 빠른 교환이 가능해지며, 복잡한 연산을 효율적으로 처리할 수 있다.
이 내용의 경우는 추후에 더 자세하게 조사해서 정리를 해봐야 겠다.
📌 Worker의 종류: Web Workers와 Service Workers 📌
공통점
- 두 종류의 워커 모두 메인 스레드와 독립된 스레드에서 스크립트를 실행한다.
- 메인 스레드의 window 및 document 객체에 접근할 수 없으며, 제한된 브라우저 API만 사용할 수 있다.
차이점
- Web Worker: 여러 개 등록할 수 있으며, 메인 스레드의 탭 생명주기에 따라 함께 종료된다. 주로 데이터 처리 및 계산에 사용된다.
- Service Worker: 도메인당 하나만 등록할 수 있으며, 네트워크 요청을 가로챌 수 있고 Push API를 사용할 수 있다. 모든 활성화된 탭에 영향을 미치며, 탭이 모두 닫혀도 백그라운드에서 계속 실행된다.
그러나 너무 오랜 시간 실행되는 작업은 사용자의 보안이나 배터리에 악영향을 줄 수 있어 강제로 종료될 수 있다. 이 경우 Background Fetch와 같은 API를 사용하여 워커의 종료를 방지할 수 있다.
'CS' 카테고리의 다른 글
SWC(Speedy Web Compiler)? (1) 2024.10.02 FE(프론트엔드)에서 어떤 test를 해야 할까? (TDD는 또 어떤 걸까?) (1) 2024.09.27 Virtual DOM(가상 DOM) (0) 2024.09.19 [TS] Typescript를 왜 쓸까? (2) 2024.09.18 자바스크립트 배열(JS array)을 다루는 메소드들 (0) 2024.08.31