브라우저 이벤트 루프

Browser event loop

태스크를 실행하고 마이크로태스크를 비운 뒤 렌더링 기회를 잡습니다.

···
html
<div class="v"><header>EVENT LOOP <span id="phase">task</span></header><div class="stage loop"><div class="q" id="q0">Task<br><b>click()</b></div><div class="q" id="q1">Microtasks<br><b>then()</b></div><div class="q" id="q2">Frame<br><b>paint</b></div><div class="token" id="token"></div></div><div class="muted">task → drain microtasks → render opportunity</div></div>
css
.v{width:min(94vw,760px);height:min(88vh,320px);padding:clamp(9px,2.4vmin,18px);border:1px solid var(--line);border-radius:12px;background:var(--surface);font:500 clamp(12px,2.4vmin,16px)/1.3 var(--font-sans,system-ui,sans-serif);display:flex;flex-direction:column;gap:clamp(5px,1.4vmin,10px);overflow:hidden}.v header{display:flex;align-items:center;justify-content:space-between;gap:8px;color:var(--accent);font-weight:700}.v header span{color:var(--muted);font-weight:500}.v .stage{flex:1;min-height:0;position:relative}.v .muted{color:var(--muted)}.v .active{background:color-mix(in srgb,var(--accent) 18%,var(--surface));border-color:var(--accent)!important;color:var(--fg)}.v button{font:inherit;color:var(--fg);background:var(--bg);border:1px solid var(--line);border-radius:7px;padding:5px 8px;cursor:pointer}.loop{display:flex;align-items:center;justify-content:space-around;gap:8px}.q{width:29%;min-height:70px;display:grid;place-items:center;text-align:center;border:1px solid var(--line);background:var(--bg);border-radius:9px;transition:.25s}.q b{font-weight:600;color:var(--accent)}.q.on{border-color:var(--accent);box-shadow:inset 0 0 0 2px color-mix(in srgb,var(--accent) 22%,transparent)}.token{position:absolute;bottom:7%;width:9px;height:9px;border-radius:50%;background:var(--accent);left:14%;transition:left .45s}
js
let i=0;const phases=["task","microtasks","frame"];function tick(){for(let j=0;j<3;j++)document.getElementById("q"+j).classList.toggle("on",i===j);document.getElementById("phase").textContent=phases[i];document.getElementById("token").style.left=(14+i*34)+"%";i=(i+1)%3}tick();setInterval(tick,800)

이벤트 루프는 한 번에 하나의 자바스크립트 태스크를 실행합니다. 태스크가 끝나면 마이크로태스크 큐를 비우고, 브라우저는 필요할 때 화면을 갱신합니다.

데모의 토큰은 태스크에서 마이크로태스크를 거쳐 프레임으로 이동합니다. 긴 동기 작업은 이 순서를 붙잡아 입력 처리와 화면 갱신을 늦출 수 있습니다.

언제 쓰나

Promise 콜백, 타이머, 렌더 지연의 실행 순서를 디버깅할 때 씁니다.

페이지로 열기 ↗