싱글 스레드 언어의 미스터리
자바스크립트는 하나의 작업이 완료된 후 다음 작업을 순차 실행하는 싱글 스레드(Single Thread) 언어입니다. 하지만 웹브라우저 상에서 타이머를 돌리고, 마우스 클릭을 감지하며, 서버에서 네트워크 패킷을 병렬로 받아오는 행위가 동시에 원활하게 일어납니다. 자바스크립트 엔진과 브라우저 런타임 환경이 협업하는 핵심 원리를 알아봅니다.
1. 런타임 주요 구성 요소
- Call Stack: 자바스크립트 코드가 실행되며 쌓이는 단일 호출 스택.
- Web APIs: 타이머(`setTimeout`), DOM 이벤트 청취, AJAX 요청 등 브라우저가 관리하는 멀티스레드 기반 처리 대행소.
- Task Queue (Callback Queue): 비동기 연산 완료 후 자바스크립트 실행 스레드로 넘겨주기 위해 대기하는 콜백 함수 대기 장소.
- Event Loop: 실시간 감시자로, Call Stack이 완전히 비어 있을 때만 Task Queue 속의 대기 콜백들을 스택으로 밀어 넣는 스레드 조율자.
2. 마이크로태스크 큐(Microtask Queue)의 우선순위
모든 비동기 대기열이 동일한 것은 아닙니다. `Promise` 객체의 `.then()`이나 `async/await` 등으로 파생되는 마이크로태스크는 일반 `setTimeout` 콜백(매크로태스크)보다 항상 최우선적으로 먼저 스택에 주입되어 처리됩니다. 비동기 동작의 정교한 실행 순서를 완벽히 파악하기 위해서는 이 우선순위를 반드시 파악해야 합니다.
이벤트 루프를 체감하는 문제 상황
이벤트 루프 지식은 면접용 개념이 아니라 UI 멈춤, 클릭 지연, Promise 실행 순서 문제를 해결하는 도구입니다. 특히 긴 동기 작업이 Call Stack을 오래 점유하면 브라우저는 사용자 입력을 처리하지 못해 화면이 멈춘 것처럼 보입니다.
개선 방법
- 큰 배열 처리나 파싱 작업은 작은 단위로 나누어 메인 스레드 점유 시간을 줄입니다.
- 렌더링 직후 처리할 작업과 사용자 입력에 즉시 반응해야 하는 작업을 구분합니다.
- 무거운 계산은 Web Worker로 옮겨 UI 스레드를 비워둡니다.
비동기 코드는 단순히 빠르게 실행되는 코드가 아닙니다. 언제 실행되고 무엇을 막는지 이해해야 안정적인 사용자 경험을 만들 수 있습니다.
참고 자료와 업데이트 기준
이 글은 실무 적용 관점에서 작성했으며, 관련 기술의 공식 문서와 브라우저 지원 현황이 바뀌면 내용을 다시 점검합니다. 특히 프레임워크 버전, API 정책, 성능 측정 방식은 시간이 지나며 달라질 수 있으므로 배포 전에는 최신 문서를 함께 확인하는 것을 권장합니다.
- MDN Web Docs에서 웹 표준과 브라우저 동작을 확인합니다.
- web.dev에서 성능, 접근성, 사용자 경험 기준을 확인합니다.
- React 공식 문서에서 React 관련 API와 권장 패턴을 확인합니다.