본문 바로가기
FrontEnd/JavaScript

브라우저 엔진의 작업 처리 우선순위 (feat. 마이크로 테스크 큐, 테스크 큐, 렌더 큐)

by 위그든씨 2024. 10. 7.

브라우저는 렌더링 엔진과 자바스크립트 엔진의 혼합으로 작업이 처리된다.

이벤트 루프에 의해 콜 스택이 비워져 있다면 큐에 담겨진 요소들을 선입선출 순서로 콜스택에서 실행시키는데,

이 때 큐의 종류에 따라 콜 스택에 담겨지는 우선순위가 달라진다. 

첫 번째로 Promise가 반환하는 resolove,reject가 담겨진 마이크로 태스크 큐,

두 번째로 렌더링 업데이트 요소들이 담겨진 렌더 큐

마지막으로 DOM 이벤트,fetch,setTimeOut,setInterval 등이 담겨진 태스크 큐 

순서로 각각의 큐에 담겨진 작업들을 콜 스택에 담은 후 처리되면 그 다음 큐, 그 다음 큐로 실행된다.

따라서, 아래와 같이 코드를 작성하더라도 setTimeout의 콜백함수는 0초에 값을 줬더라도 즉시 실행되지않고 1과 3이 출력 된 후 실행되어 최종적으로 1 - 3- 2 가 콘솔창에 찍힌다.

console.log("1")

setTimeout(()=>{console.log("2")},0)

console.log("3")

또다른 예시로는 setTimeout 다음에 Promise 가 반환 중이더라도 Promise의 콜백이 마이크로 태스크 큐에 담겨져 우선순위가 더 높아서 해당 콜백이 실행된 이 후  setTimeout의 콜백이 실행된다.

** 위의 언급한 큐들의 우선순위는 마이크로->렌더->태스크 순이라고 얘기했지만, 실제로 아래의 코드를 실행해보면 alert이 호출 된 이후 

렌더링 업데이트가 발생하는 걸 볼 수있다.

document.body.innerHTML = 'ㅊinnerHTML';

setTimeout(() => {
	alert('Alert!');
});

우선 순위는 렌더 큐가 높지만 alert이 뜬 후 렌더링이 되는 이유는 이벤트 루프는 매 반복시마다 마이크로와 태스크 큐를 방문하여 작업을 확인하지만 렌더 큐에는 0.016s 의 주기로 방문하여 실행 될 것이 있는지 확인하기 때문이다. => 렌더링 최적화랑 연관이 있는듯?