웹브라우저가 HTML, CSS, JavaScript 파일을 받아 실행할 때 내부에서 어떻게 Stack과 Queue를 활용하는지 알아봅니다. 이 내용을 이해하면 이벤트리스너, setTimeout 등 비동기 처리와 관련한 동작 원리를 파악하여 효율적인 코드를 작성하는 데 도움이 됩니다.
1️⃣ 웹 브라우저의 기본 역할
- 웹 브라우저는 서버로부터 HTML, CSS, JS 파일을 받아서 실행하는 프로그램입니다.
- 브라우저는 자바스크립트 코드를 처리할 때 C++ 등으로 작성된 내부 엔진을 사용합니다.
- 내부적으로 코드를 실행하는 Stack(호출 스택)이 존재하며, 여기에서 코드를 순차적으로 실행합니다.
2️⃣ Stack과 Queue의 역할
Stack (호출 스택)
- 정의:
- 코드를 순차적으로 쌓고, 맨 위에서부터 하나씩 실행하는 구조입니다.
- 동작 원리:
- 브라우저는 자바스크립트 코드를 만나면 이를 C++로 작성된 Stack에 넣어 실행합니다.
- 단순하고 빠른 작업은 모두 Stack에서 처리됩니다.
Queue (작업 큐)
- 정의:
- Stack이 아닌, 시간이 오래 걸리는 작업(예: ajax 요청, 이벤트리스너, setTimeout)을 보류하기 위한 공간입니다.
- 동작 원리:
- ajax 요청, 사용자 이벤트, 타이머 등의 작업은 즉시 처리하지 않고 Queue에 대기시킵니다.
- Stack이 비어있는 시점에 Queue에 있는 작업들이 순서대로 Stack으로 옮겨져 실행됩니다.
- Queue는 들어온 순서대로 작업을 처리합니다.
3️⃣ 웹브라우저 동작 원리와 코드 작성 시 주의사항
문제 상황: Stack이 바쁠 때
- 예시:
- 반복문을 1억번 또는 100억번 실행하는 경우
- 이런 작업이 진행되는 동안 Stack은 계속 바쁘기 때문에, ajax 요청이나 이벤트리스너, setTimeout 등 대기 중인 작업들이 실행되지 않습니다.
- 결과:
- 웹사이트가 버벅거리거나, 사용자 이벤트에 반응하지 않아 브라우저가 멈추거나 하얗게 변할 수 있습니다.
해결 방안
- setTimeout 활용하기
- 아이디어:
- 긴 반복문을 한 번에 처리하는 대신, 작은 단위로 나누어 실행하도록 setTimeout을 사용합니다.
- 예시:
- 0초마다 0
1억 반복, 1억2억 반복, … 이렇게 분할하여 실행하면, 각 작업 사이에 Queue에 쌓인 이벤트(예: 버튼 클릭 등)를 처리할 수 있습니다.
- 참고:
- setTimeout의 최소 실행 시간은 0초로 설정하더라도 실제로는 최소 4ms 정도로 동작합니다.
- Web Worker 사용하기
- 아이디어:
- 무거운 연산 작업은 별도의 스레드에서 실행하여 메인 스레드(메인 JS 파일)의 Stack이 바쁘지 않도록 합니다.
- 사용법:
- 효과:
- 연산 작업을 별도의 스레드에서 수행함으로써 메인 Stack이 바쁘지 않게 되어, 사용자 이벤트나 타이머 작업 등이 원활하게 처리됩니다.
📌 정리
- 브라우저의 내부 동작 원리:
- Stack: 자바스크립트 코드가 순차적으로 실행되는 공간
- Queue: 비동기 작업(ajax, 이벤트, 타이머 등)을 대기시키는 공간
- 코드 작성 시 주의사항:
- 무거운 작업으로 Stack을 장시간 바쁘게 만들지 않도록 주의해야 합니다.
- 긴 반복문이나 무거운 연산이 필요한 경우, setTimeout 또는 Web Worker를 사용하여 비동기적으로 처리함으로써 브라우저가 원활하게 동작하도록 설계해야 합니다.
- 실제 코딩 생활에의 적용:
- 이벤트리스너, ajax 요청, setTimeout 등의 비동기 작업이 예상치 못하게 동작하는 이유를 이해하고, 이를 고려한 최적화된 코드를 작성할 수 있습니다.