이번 글은 setTimeout 0 성능 최적화 방법을 활용하여 인라인 스크립트 지연 로딩을 구현함으로써, 애드센스 광고 로딩 속도 개선 및 블로그 랜더링 최적화 방법 입니다.또한 블로그 LCP 점수 올리는 방법과 워드프레스 TTI 개선 하는 방법을다룹니다.
구글 페이지스피드 인사이트 점수 최적화를 위한 브라우저 메인 스레드 점유율 낮추기고Core Web Vitals 성능 개선 실무 방법
웹 성능의 핵심 지표인 코어 웹 바이탈(Core Web Vitals) 점수를 올리기 위한 아주 영리한 방법을 하나 소개해 드리려고 합니다. 많은 블로거와 개발자들이 LCP(최대 콘텐츠 렌더링 시간)나 TTI(상호작용 시작 시간) 점수 때문에 골머리를 앓고 있죠.
특히 티스토리나 워드프레스처럼 내가 소스코드를 100% 제어하기 힘든 CMS 환경에서는 외부 스크립트보다 인라인 스크립트가 성능의 발목을 잡는 경우가 많습니다. 이때 구원투수로 등장하는 것이 바로 setTimeout(…, 0)입니다. 지연 시간 0인데 이게 효과가 있어? 라고 의문을 가지시는 분들을 위해 그 원리와 적용 방법을 정리해 드립니다.
setTimeout(…, 0)의 마법: 왜 성능이 좋아질까?
결론부터 말씀드리면, setTimeout(…, 0)의 목적은 기다림이 아니라 순서 바꾸기에 있습니다. 이는 자바스크립트 비동기 처리의 핵심을 이용하는 원리입니다.
1. 메인 스레드 비우기
setTimeout(…, 0)의 주된 목적은 코드를 바로 실행하는 것이 아니라, 현재 실행 중인 모든 동기(synchronous) 코드와 브라우저가 수행해야 하는 렌더링 작업(Rendering tasks)이 완료된 후에 실행되도록 코드를 Task Queue로 밀어 넣는 것입니다.
- 비동기 처리: 자바스크립트(avaScript}은 싱글 스레드(Single-threaded) 환경이므로, 긴 스크립트가 실행되면 브라우저의 UI 렌더링을 막게 됩니다. setTimeout은 이 코드를 비동기적으로 처리하여, 브라우저가 먼저 화면을 그리고(LCP, FCP 개선) 나서 해당 코드를 실행할 수 있는 기회를 줍니다.
- Time To Interactive (TTI) 개선: 사용자 경험(UX) 관점에서, 페이지가 사용자의 입력에 반응할 수 있는 시간인 TTI를 단축하는 데 유용한 방법입니다.
2. 작동 원리 (매크로 태스크)
setTimeout의 지연 시간(Delay)을 0으로 설정하더라도, 실제로는 브라우저의 최소 지연 시간(Minimum delay)이 적용됩니다(일반적으로 4ms). 더 중요한 것은, 이 함수가 생성하는 작업은 매크로 태스크(Macrotask)에 속하며, 현재 실행 중인 콜 스택(Call Stack)이 완전히 비워지고 렌더링이 완료된 후에야 이벤트 루프(Event Loop)에 의해 실행된다는 점입니다.
- 콜 스택(Call Stack) 비우기: 현재 실행 중인 모든 동기 코드가 끝나야 합니다.
- 렌더링 완료: 브라우저가 한 프레임의 화면을 다 그린 후에야 이벤트 루프가 태스크 큐에 있는 setTimeout 코드를 가져와 실행합니다.
즉, 화면 먼저 다 그리고 나서, 남는 시간에 이 코드를 처리해! 라고 브라우저에게 명령하는 아주 효율적인 방식인 것이죠.

메인 스레드에게 숨통을 틔워주다
자바스크립트는 싱글 스레드(Single-threaded)로 작동합니다. 브라우저가 HTML을 읽다가 긴 스크립트를 만나면 화면을 그리는 작업을 멈추고 그 코드를 실행하는 데 매달립니다. 이때 사용자 화면은 멈추고 LCP 점수는 깎이게 되죠.
하지만 코드를 setTimeout(…, 0)으로 감싸면 다음과 같은 변화가 일어납니다.
- 태스크 큐(Task Queue)로 이동: 해당 코드는 즉시 실행되지 않고 대기 명단(Task Queue)의 맨 뒤로 밀려납니다.
- 렌더링 우선권 부여: 브라우저는 스크립트 실행 대신 화면 그리기(Rendering) 작업을 먼저 완료합니다.
- 성능 지표 개선: 화면이 빨리 뜨니 FCP, LCP 점수가 올라가고, 메인 스레드가 비워지니 사용자가 버튼을 눌렀을 때 반응하는 TTI 점수도 개선됩니다.
다른 최적화 방식과의 비교
성능 최적화의 목표는 HTML 파싱을 차단하지 않고, 스크립트를 가능한 한 늦게 실행하는 것입니다. 아래 표는 인라인 스크립트 지연 로딩과 외부 스크립트 최적화 방식을 비교한 것입니다.
| 방식 | HTML 파싱 차단 | 실행 시점 | 주요 이점 |
|---|---|---|---|
| setTimeout(…, 0) | 차단 안 함 (비동기) | DOMContentLoaded 후, 현재 이벤트 루프 작업 완료 직후 | 기존 인라인 코드를 쉽게 지연시켜 LCP/TTI 개선. |
| script defer | 차단 안 함 (병렬 다운로드) | DOMContentLoaded 발생 직전 (순서 보장) | 외부 스크립트의 순서 보장 및 파싱 완료 직전 실행. |
| script async | 차단 안 함 (병렬 다운로드) | 다운로드 완료 즉시 (순서 비보장) | 가장 빠른 실행이 필요할 때 (예: 광고, 애널리틱스). |
언제 setTimeout(…, 0)이 최적의 선택인가?
실무 경험상, 다음 조건에서는 setTimeout(…, 0)이 다른 어떤 방식보다 강력합니다. 특히 브라우저 메인 스레드 점유율 낮추기에 필수적입니다.
- CMS(티스토리, 워드프레스) 환경: 외부 파일로 분리하거나 defer 속성을 넣기 힘든 인라인 스크립트 구조일 때 가장 현실적인 대안입니다.
- 비필수적 로직: 광고 지연 로딩, 푸터 위젯 초기화, 사용자 행동 추적 코드 등 페이지 로드 즉시 실행될 필요가 없는 코드에 적합합니다.
- 레이아웃 기반 계산: 요소의 offsetWidth나 getBoundingClientRect 등을 계산해야 하는 로직은 반드시 렌더링이 끝난 후 실행되어야 성능 저하(레이아웃 스래싱)를 막을 수 있습니다.
- 애니메이션 초기화: 화면이 다 그려진 후 애니메이션이 시작되어야 부드러운 UX를 제공합니다.
핵심 요약 및 주의사항
Core Web Vitals 성능 개선 실무 팁의 핵심 우선순위는 다음과 같습니다.
스크립트 최적화 우선순위
- 외부 스크립트는 무조건 defer 사용
- 분석/광고 스크립트는 async 활용
- 인라인 스크립트나 렌더링 후 실행이 필요한 로직은 setTimeout(…, 0)
⚠ 주의할 점 (FOUC 방지)
이미지 슬라이더나 상단 메뉴처럼 사용자가 바로 봐야 하는 시각적 요소를 초기화하는 코드에 setTimeout을 쓰면 화면이 깜빡거리는 FOUC(Flash of Unstyled Content) 현상이 발생할 수 있습니다. 이런 시각적 요소는 가급적 지연시키지 않는 것이 좋습니다.
setTimeout(0)을 사용하면 무조건 LCP 점수가 좋아지나요?
인라인 스크립트가 메인 스레드를 점유하여 렌더링을 방해하고 있었다면 확실히 LCP 개선 효과가 있습니다. 하지만 이미지가 늦게 뜨는 원인이 서버 응답 속도나 이미지 크기 자체에 있다면 효과가 제한적일 수 있습니다.
setTimeout(0)과 defer의 차이점은 무엇인가요?
defer는 외부 자바스크립트 파일을 HTML 파싱과 병렬로 다운로드한 뒤 파싱 완료 시점에 실행하는 방식입니다. 반면 setTimeout(0)은 이미 HTML에 포함된 인라인 스크립트의 실행 순서를 브라우저 렌더링 이후로 미룰 때 사용합니다.
티스토리에서 광고 스크립트에 이 방식을 적용해도 되나요?
네, 매우 효과적입니다. 티스토리의 하단 광고나 사이드바 위젯 스크립트를 setTimeout(0)으로 감싸면 초기 로딩 속도를 높여 사용자 경험을 개선하고 검색 엔진 최적화 점수를 높일 수 있습니다.
일하는 방식의 차이가 한 끗 차이의 점수를 만듭니다
setTimeout(…, 0)은 단순히 코드를 늦게 실행하는 꼼수가 아닙니다. 브라우저의 작동 원리를 이해하고 리소스 분배를 최적화하는 전략적 선택입니다.
지금 블로그 하단에 들어있는 무거운 인라인 스크립트들을 setTimeout으로 감싸보세요. 구글 페이지스피드 인사이트 점수가 눈에 띄게 올라가는 것을 경험하실 수 있을 겁니다.