alert와 렌더링

문제 상황

우선 다음 코드를 읽어보자.

// 버튼의 클릭수
let clickCnt = 2;

$button.addEventListener('click', (e) => {
  // 버튼의 스타일을 변형하는 코드
  if ($button.style.textDecoration === 'line-through') {
    $button.style.textDecoration = '';
  } else {
    $button.style.textDecoration = 'line-through';
  }
    
  clickCnt++;
  //세번 클릭시 alert창 표시  
  if(clickCnt % 3 === 0) {
    alert('3번째 클릭!');
  }
})

버튼을 클릭하면 이벤트 핸들러가 호출되고 버튼의 스타일을 변경 후 alert이 등장할 것처럼 보인다. (버튼 클릭 -> 스타일 변형 -> alert 창 등장)

그러나,
실제로 브라우저 창에서 확인해 보면 버튼의 스타일이 변경되기 전에 alert창이 먼저 등장하고 창을 닫아야 버튼의 스타일이 변경된다.

실제로 무슨일이 일어나는 지 알아보자.

우선, 브라우저에서 무슨일이 일어나는지 알아보기 위해 개발자도구를 열어보았다.

다음 사진을 살펴보자

위 사진을 위에서부터 순차적으로 살펴보면 'click'이벤트가 발생시 이벤트 핸들러가 호출되고 alert 또한 호출되는 것을 알 수 있다. 첫번째 빨간줄 전후로 시간을 살펴본다면 alert호출이후 브라우저는 어떠한 행동도 하지 않고 정지 상태로 멈춰있다. 이후 alert창을 닫은 이후에야 작업을 시행하고 마지막줄에 이르어서야 paint를 실행하여 변경된 스타일을 화면에 출력한다.

그렇다면 setTimeout을 이용해서 alert의 호출을 지연한다면 어떻게 될까??

let clickCnt = 2;

$button.addEventListener('click', (e) => {
  // 버튼의 스타일을 변형하는 코드
  if ($button.style.textDecoration === 'line-through') {
    $button.style.textDecoration = '';
  } else {
    $button.style.textDecoration = 'line-through';
  }
    
  clickCnt++;
  //세번 클릭시 alert창 표시  
  if(clickCnt % 3 === 0) {
    setTimeout(() => alert('3번째 클릭!'));
  }
})

다음은 setTimeout의 지연시간을 0으로 설정(실제로는 0은 아니다.)후에 alert의 호출을 지연했을 때의 상황이다.

역시나 위에서 부터 살펴보면 버튼을 'click'하면 이벤트 핸들러를 호출한다. 이벤트 핸들러안의 setTimeout이 Timer Fired 이후에야 alert이 호출한다는 것을 알 수 있다. 그로 인해 paint과정이 빨리 나타나게 되고 실제로도 버튼의 스타일의 변경 후 alert 창이 등장하는 것을 확인할 수 있다.

좋은 웹페이지 즐겨찾기