프론트엔드에게 setTimeout 함수는 단순한 함수가 아니다!!!

일단, 지금 내가 좆같이 외부망 막힌 프론트엔드 개발짓거리 하고 있는 관계로 블로그질을 잘 못하겠지만,
이런 일을 자주 겪어 존나 머리가 쌓이기만 하기에 내 메모리 릴리즈 하는 개념으로 글 씨지르겠다.

프론트엔드 개발하다 보면 이런 경우를 겪는다. 특히 화면 변경할때 말이지.
화면을 변경하다 보면 갑자기 스크립트 오류가 나거나, 원하는 화면이 안나올 때가 있다.
이것으로 머리 싸매다가, 안되겠다. 지연시켜서 뿌려야겠다는 생각으로 setTimeout 함수를 쓰면
원하는 화면변경이 이루어진다. 이상할 정도로.
더 웃긴 현싱은, 타임아웃 주기를 0으로 해도 잘된다는 것이다. 이게 대체 어떻게 된 거지?

먼저, 자바스크립트는 싱글 쓰레드라는 것. 아주 질리도록 들었을 것이다. 비동기도.

하지만 잊지 말아야 할 점은 이 싱글 쓰레드가 하필 화면을 표현하는 렌더링 시점에도 블로킹 현상이 일어나는 점을 간과해서는 안된다.
즉, 스크립트 실행중인 시점에 DOM에 어떤 변화가 찾아올 지 우린 예상할 수 없다는 것이다. 왜냐? 싱글 쓰레드로 하나씩만 진행하기 때문에.
그럼 왜 setTimeout 함수는 회피할 수 있을까? 간단하다.
위 그림을 보면 setTimeout 블록으로 등록된 timer 스레드는 그저 다음 실행 시점으로 예약만 하고 이 스레드에 도달해야 실행되기 때문이다.
그렇다면 왜 setTimeout은 분명 1초인데 1초 빨리 실행하거나 1초보다 늦게 실행하기도 하는가?
먼저, node.js 개발해본 시람은 알겠지만 거기는 setTimeout 함수는 없고 process.nextTick 함수를 사용한다. 그렇다.
원리는 비슷하다. 빠르게 tick 하면서 스크립트가 실행된다. 게임이나 영상으로 치자면 프레임 단위에 무슨 이벤트가 일어난다는 것이다.
보통 1 tick 하면 1/1백만 초다. 백만분의 1초. 하지만 setTimeout은 아무리 최소값이라도 4/1000초.
클라이언트 스크립트에서 tick 단위를 허용기엔 가뜩이나 렌더링이 스레드 예약하고 블록거는데 무슨 일이 일어날 지 검증이 안 된 상황.
자, 일단 여김가지 갔으면 이제 setTimeout 함수로 예약한 함수 루틴은 나머지 구문을 실행한 후 실행하는 것을 알 수 있다.
즉, 렌더링에 시간을 벌어주어 렌더링 후 화면 변경에 대한 정보를 불러오고 쓰는 데 정확도를 높일 수 있는 그런 트릭인 것이다.
그런 고로 화면을 변경할 때, 특히 DOM 데이터를 주고받거나 다룰 때 setTimeout 함수는 DOM 렌더링 시간을 벌어주어 원하는 사용자 처리를 도와주는 프론트엔드에게 고마운 함수인 것이다. 감사하며 쓰도록 하자.

참고: Why is setTimeout(fn, 0) sometimes useful?

composite / 2017년 1월 9일 / Piss Development / 1 Comment