
현재 진행중인 프로젝트에서 보안상의 이유로
일정 시간 동안 사용자가 아무런 활동을 하지 않으면 자동 로그아웃이 필요함.
기존에setTimeout을 사용해서 일정 시간이 지나면 로그아웃하는 방식으로 구현되었으나,
브라우저 탭이 비활성화되거나 시스템이 절전 모드로 들어가면setTimeout의 정확도가 떨어지는 문제가 있음.
이를 해결하기 위해서 개선된 방식인 웹 워커를 활용한 경험을 정리해서 공유드리고자 합니다.
네, 맞습니다. JS는 싱글 스레드 언어이지만, JS가 돌아가고 있는 엔진은 브라우저에 속해있습니다.
브라우저는 멀티 스레딩을 지원하고 있고, 웹 워커가 해당 멀티 스레딩 중 백그라운드 스레드에 속해 있습니다.
그러므로 Workers API 는 JS에서 지원하는 기능이 아닌, Web API의 기능입니다.
최신 브라우저는 Web Worker 기능을 지원한다고 볼 수 있습니다.
출처: TCP School
ng generate web-worker /shared/workers/session-timersrc/app/shared/workers/session-timer.worker.ts 파일 생성.angular.json)에 워커를 번들링하도록 자동 추가.tsconfig.worker.json 파일 생성: TypeScript가 웹 워커를 인식하도록 설정 src/
├── app/
│ ├── shared/
│ │ ├── workers/
│ │ │ ├── session-timer.worker.ts
│ │ │ └── another.worker.ts
│ │ └── services/
│ │ ├── session-timeout.service.ts
│ ├── components/
│ └── app.module.ts
├── assets/
├── angular.json
├── tsconfig.app.json
├── tsconfig.worker.json
setTimeout을 통해 구현하려던 세션 타이머 서비스 코드
setTimeout 세션 타이머의 결함session-timer.worker.tssession-timeout.service.ts
addEventListener('message', ...) (메시지 리스너 등록)
new URL('../../workers/session-timer.worker', import.meta.url)을 사용하여 웹 워커 파일을 동적으로 불러옴.import.meta.url은 현재 모듈의 URL을 가져오는 방식.type: 'module'은 웹 워커를 ES 모듈로 로드할 수 있도록 설정.this.worker.postMessage(timeoutDuration);session-timer.worker.ts파일의 이벤트 리스너에서 { data }로 사용됨.this.worker.onmessage = ({ data }) => { ... }
웹 워커는 메인 스레드의 영향을 받지 않고 백그라운드에서 안정적인 타이머 처리를 가능하게 해주는 강력한 도구이지만 몇 가지 단점도 존재합니다.
브라우저 지원 범위
최신 브라우저에서는 대부분 지원하지만 구형 브라우저나 일부 제한된 환경(내장 브라우저 등)에서는 호환성 문제가 발생할 수 있습니다.
DOM 접근 불가
웹 워커는 백그라운드 스레드에서 동작하기 때문에 DOM을 직접 조작할 수 없습니다. 이는 UI 업데이트가 필요한 로직에서는 메인 스레드와의 메시지 통신을 거쳐야 하므로 구조가 복잡해질 수 있습니다.
디버깅이 상대적으로 어려움
워커는 별도 스레드에서 실행되므로 콘솔 로그가 메인 스레드와 분리되어 나오고 디버깅 도구에서도 별도로 확인해야 하기에 디버깅이 다소 불편할 수 있습니다.
리소스 관리 필요
웹 워커는 명시적으로 종료하지 않으면 계속 실행되므로 불필요한 리소스 점유를 방지하기 위해 terminate() 등을 통해 수동으로 종료 관리를 해주어야 합니다.
기존 setTimeout 방식은 브라우저 탭이 비활성화되거나 시스템이 절전 모드로 들어가면 정확도가 떨어지는 문제가 있었습니다. 이를 해결하기 위해 웹 워커를 활용해 독립적인 스레드에서 타이머를 실행하는 방식으로 개선했습니다.
웹 워커를 사용하면 메인 스레드가 차단되지 않고 브라우저 환경에 관계없이 일정한 주기로 타이머를 유지할 수 있습니다.
그 결과 세션 타임아웃 감지를 더 안정적이고 정확하게 수행할 수 있었고 웹 애플리케이션의 보안성을 강화할 수 있었습니다.