자 지금까지 다양한 종류의 워커를 알아보았습니다. 사실 Shared Worker와 Service Worker는 단순 추가적인 쓰레드를 활용한다기 보다는 특별한 종류의 작업을 처리하는 것에 더 가까운 것같습니다. 제목인 자바스크립트와 "멀티 쓰레드"와는 조금 맞지 않은 부분이 있습니다.(제목을 자바스크립트와 워커들 같은 식으로 지었어야했나봅니다.)
하지만 오늘 다룰 워커는 멀티 쓰레드라는 제목과 가까운 워커입니다. 바로 Dedicated Worker인데요. 한국말로 번역해 보자면 전용 워커 정도가 될 것입니다. Dedicated는 "헌식적인"이라는 뜻도 있지만 "특정한 목적을 위한"이라는 뜻도 있습니다. 그리고 Dedicated Worker는 이 뜻에 훨씬 잘 들어 맞죠. 그리고 별 다른 언급없이 워커를 지칭한다면 바로 이 전용 워커를 의미합니다. 현재 글 시리즈의 가장 처음에 소개한 워커도 바로 전용 워커입니다. 하지만 전용 워커를 포함해 이전에 소개 드린 3가지 워커 외에 다른 워커가 더 존재합니다. 오늘은 이 워커들에 대해 "간단하게" 알아보도록 하겠습니다.
Worklet
The Worklet interface is a lightweight version of Web Workers and gives developers access to low-level parts of the rendering pipeline.
MDN에서는 워크렛(workelet)을 위와 같이 소개하고 있습니다. 해석하자면, "워크렛은 웹 워커의 가벼운 버전이며, 개발자는 워크렛으로 렌더링 과정의 저수준에 접근(제어)할 수 있다"는 뜻입니다.
가볍다는 것은 웹 워커보다 가벼운 실행 환경을 가진다는 말입니다. 풀어서 설명하면 메모리 사용량이 적고 실행속도가 빠르다는 의미입니다. 새로운 쓰레드를 생성해 사용하는 웹 워커와는 다르게 브라우저 내부의 특정한 환경에서 동작하는 워커로 메인 쓰레드와는 별개이지만 브라우저 내부에 존재하고 사용되던 쓰레드를 사용하기 때문에 쓰레드를 생성하는 비용이 없습니다. (일반적으로 쓰레드 생성의 비용은 꽤 큰 편입니다.)
렌더링 파이프라인의 저수준은 (CSS)애니메이션, 오디오 처리, CSS 레이아웃, 공유 저장소에 대한접근을 말합니다. 앞서 말했듯이 브라우저 내부의 특정 환경에서 실행되는 데 이 환경에서 접근 가능한 요소(API)들이 바로 Web Audio API, CSS Animation Worklet API, CSS Layout API, Shared Storage API입니다. 각각의 워크렛은 Worklet
클래스를 상속받았으며, 역할을 표로 나타내면 다음과 같습니다.
API | 설명 | 실행 위치(쓰레드) |
---|---|---|
Web Audio API | 오디오 처리 | Web Audio 렌더 스레드 |
CSS Animation Worklet API | 스크롤 연동 애니메이션 등 고성능 애니메이션을 구현 | Compositor 스레드 |
CSS Layout API | 사용자 정의 레이아웃을 정의하고 요소의 위치와 크기를 설정 | 정해지지 않음 |
Shared Storage API | 사이트 간 데이터를 안전하게 처리하고, 개인 정보 보호를 강화 | 메인 쓰레드 |
다시 알아듣기 쉽도록 정리하자면 워크렛은 CSS 애니메이션, 오디오 처리, CSS 레이아웃 관련 작업에 접근할 수 있는 특별한 위치에서 실행되는 워커입니다. 각각의 워크렛을 이용하는 API는 메인 쓰레드에서도 실행 가능하지만 복잡한 작업이 포함될 경우 성능이 뛰어나고 지연 시간이 낮은 워크렛 API 사용을 고려해 볼 수 있습니다.
참고로 MDN 문서에서도 나와 있듯이 CSS Painting API에 정의된 Paint worklet은 워크렛의 서브 클래스가 아닙니다! CSS Painting API에서 정의된 Paint Worklet은 Worklet 인터페이스를 상속받지 않는 별도의 시스템입니다. 워크렛의 인스턴스를 사용하는 것이 아닌 CSS Painting API를 위해 등록하여 워크렛처럼 사용하는 자바스크립트 클래스입니다.
뭐, 개인적으로는 실제 개발에서 Worklet 기능을 사용할 일은 거의 없을 것 같습니다.
WASM
사실 웹어셈블리가 워커와 직접적으로 연관되어 있지는 않습니다. 다만 싱글쓰레드 언어에더 멀티 쓰레드를 사용하는 언어를 WASM을 이용해 브라우저에서 실행할 때, 워커가 멀티쓰레드의 역할을 해줍니다.
Worker의 보충 설명
사실 이 시리즈의 마지막 글을 쓰려는 목적은 워커에 대한 추가적은 설명을 조금 하는 김에 위의 내용을 덧붙이려는 목적이었습니다. 추가적인 메서드와 옵션에 대해 간략하게 설명만 하고 글을 마치겠습니다.
워커 생성자의 옵션
워커를 사용할 때, 각 워커 인스턴스는 특정한 설정을 통해 그 동작 방식을 다르게 할 수 있습니다. 이런 설정들을 바로 '옵션'이라 부릅니다.
첫 번째는 type
입니다. 이 옵션은 워커의 종류를 지정하는데, classic
과 module
두 가지 선택지가 있습니다. classic
은 기본값으로, 전통적인 방식의 워커를 의미합니다. module
을 선택하면, ES 모듈을 사용할 수 있습니다. 기본적으로는 classic
입니다.
다음은 credentials
입니다. 이 설정은 워커에서 네트워크와 요청 관련된 자격 증명(쿠키, 인증 헤더 등)의 처리 방식을 지정합니다. omit
, same-origin
, include
라는 세 가지 값이 있으며, 각각 워커가 요청하는 자격 증명 데이터를 어떻게 처리할지 정합니다. 기본값인 same-origin
은 동일 출처의 요청에만 자격 증명을 포함시키기 때문에, 외부 API를 호출하는 경우에는 include
로 설정해줘야 할 수 있습니다. omit
은 자격 증명을 아예 포함하지 않습니다.
단, 워커 생성 시에는 omit
으로 생성했더라도 워커 내부에서 자격 증명을 포함하도록 변경할 수 있기 때문에 무작정 믿지는 못합니다. 반대로 유연하다고 생각할 수도 있겠지만요.
name
은 이 워커를 식별할 수 있는 이름을 설정하는 옵션입니다. 디버깅을 할 때나 워커의 로그를 추적할 때 유용합니다. 각 워커에 고유한 이름을 붙이면, 나중에 어떤 워커에서 문제가 발생했는지 쉽게 알 수 있습니다. 코틀린의 코루틴에서도 각 코루틴에 이름을 붙일 수 있는데, 코틀린의 코루틴 사용 경험이 있다면 익숙하실 것 같습니다.
인스턴스 메서드
지난 포스트 동안 postMessage
메서드만 알려드렸는데요. terminate
라는 메서드도 존재합니다. terminate
메서드는 워커를 즉시 종료시키는 메서드입니다. terminate라는 무서운 이름답게 워커가 작업 중이더라도 워커를 종료시킵니다. 만약 코루틴처럼 워커가 작업을 마친 뒤 종료하도록 만들고 싶다면 특정 플레그를 담은 상태로 워커로 메시지를 보내고, 워커는 해당 메시지를 받으면 종료 플레그를 켠 상태로 변경합니다. 그리고 종료 가능한 시점에 다시 메인 쓰레드로 메시지를 보낸 뒤, 메인 쓰레드가 terminate
메서드를 사용할 수 있게 만들어야 합니다. 코루틴에 비하면 상당히 빈약하고 번거롭지만 현재로써는 유일한 방법입니다.
에러 이벤트
워커 사용 시 볼 수 있는 에러는 크게 두 가지입니다. 하나는 워커 코드 실행 중 발생하는 이벤트로 onerror
를 통해 해당 에러 발 생 후 처리할 수 있습니다.(error를 이름으로 하는 이벤트 리스너를 부착해도됩니다.) 이 처리는 워커 내부에서 워커가 처리하는 것과 별개로 메인 쓰레드에서 워커 에러 상황을 처리할 때 사용합니다. 반면 meesageError
가 있는데요. 이 에러는 워커가 역직렬화 즉, 해석할 수 없는 메시지를 받았을 경우 발생하는 에러입니다.
마무리
놀랍게도 워커와 관련해 알아 둘 것은 이게 전부입니다. 여기에 이전에 설명했던 각 워커의 동작 방식과 예시, 그리고 메시지를 전달하는 방법만 알면 워커에 대해서는 충분합니다. 물론, 여러 워커를 동시에 사용한다면 동시성과 같은 문제가 발생할 수 있습니다. 왜냐하면 워커에게 전달한 메시지는 (Transferable objects가 아니라면) 메시지를 읽고 처리하는 동안 메인 쓰레드를 포함한 다른 쓰레드가 중간에 값을 바꾸는 것이 가능하기 때문입니다. 따라서 워커를 사용할 때는 그동안 상대적으로 거의 신경을 쓰지 않았던 문제도 새로 생길 수 있다는 점을 항상 염두에 두시길 바랍니다.
참고자료
MDN, Worklet
'개발 > JavaScript' 카테고리의 다른 글
워커를 더 효율적으로 사용하는 워커풀(Worker Pool) 개발기 (0) | 2025.04.13 |
---|---|
자바스크립트와 멀티 쓰레드 3 - Service Worker로 백그라운드에서 네트워크다루기 (0) | 2025.02.08 |
자바스크립트와 멀티 쓰레드 2 - Shared Worker로 여러 탭과 창의 데이터를 공유하기(+추상화하여 메모리 관리하기) (0) | 2025.01.28 |
자바스크립트와 멀티 쓰레드 1 - 자바스크립트가 싱글 쓰레드라고 불리는 이유와 Worker로 여러 개의 쓰레드 사용하기 (0) | 2025.01.11 |
자바스크립트 await는 이벤트 루프 내에서 어떻게 동작할까 (0) | 2024.10.23 |