다음 페인트까지의 상호작용 시간

Interaction to Next Paint

입력부터 다음 화면 갱신까지의 지연을 상호작용 전체에서 살핍니다.

···
html
<div class="atlas"><div class="head"><b>INP · input to paint</b><span class="pulse"></span></div><div class="stage"><div class="inp-button box" id="inp-button">Click action <span id="inp-cursor">↖</span></div><div class="inp-rail"><div class="inp-part"><i id="inp-a"></i><span>input wait</span></div><div class="inp-part"><i id="inp-b"></i><span>handler</span></div><div class="inp-part"><i id="inp-c"></i><span>paint</span></div></div><div class="inp-result mono" id="inp-result">waiting for input</div></div></div>
css
.atlas{width:min(94vw,720px);height:min(88vh,320px);border:1px solid var(--line);border-radius:14px;background:var(--surface);padding:clamp(10px,2.5vmin,18px);display:flex;flex-direction:column;gap:clamp(7px,2vmin,12px);font:500 clamp(12px,3.2vmin,16px)/1.25 var(--font-sans),sans-serif;color:var(--fg);box-shadow:0 8px 28px rgba(0,0,0,.06)}.head{display:flex;align-items:center;justify-content:space-between;color:var(--accent);letter-spacing:.03em}.pulse{width:8px;height:8px;border-radius:50%;background:var(--accent);animation:blink 1.3s infinite}@keyframes blink{50%{opacity:.2}}.stage{flex:1;min-height:0;position:relative;overflow:hidden}.mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace}.muted{color:var(--muted)}.accent{color:var(--accent)}.box{border:1px solid var(--line);border-radius:8px;background:var(--bg)}.inp-button{position:relative;width:60%;height:35%;margin:0 auto;display:grid;place-items:center;color:var(--accent);font-weight:700}.inp-button.flash{background:color-mix(in srgb,var(--accent) 16%,var(--bg))}#inp-cursor{position:absolute;right:2%;bottom:-10px;font-size:1.6em;animation:point 2.8s infinite}@keyframes point{50%{transform:translate(-5px,-10px)}}.inp-rail{display:flex;gap:3px;margin-top:12px;height:35%}.inp-part{flex:1;position:relative;border-radius:5px;background:var(--line);overflow:hidden;text-align:center;display:grid;place-items:center;font-size:12px}.inp-part i{position:absolute;inset:0;transform:scaleX(0);transform-origin:left;background:color-mix(in srgb,var(--accent) 30%,var(--bg));transition:transform .25s}.inp-part i.on{transform:scaleX(1)}.inp-part span{position:relative}.inp-result{text-align:right;color:var(--accent);margin-top:7px}
js
let phase=0;const parts=['inp-a','inp-b','inp-c'];function tick(){parts.forEach((id,i)=>document.getElementById(id).classList.toggle('on',i<=phase));document.getElementById('inp-button').classList.toggle('flash',phase===2);document.getElementById('inp-result').textContent=['input delayed','handler running','next paint visible','new interaction'][phase];phase=(phase+1)%4}tick();setInterval(tick,700)

INP는 클릭, 탭, 키 입력의 반응성을 나타내는 Core Web Vital입니다. 입력 지연, 이벤트 핸들러 처리, 다음 프레임 표시까지 걸린 시간을 합쳐 봅니다.

데모는 세 구간이 순서대로 채워지는 모습을 보여줍니다. 핸들러만 빠르게 고쳐도 메인 스레드가 바쁘거나 렌더가 늦으면 사용자가 느끼는 반응은 여전히 느립니다.

언제 쓰나

버튼이나 입력창이 늦게 반응할 때 실제 사용자 데이터와 트레이스를 함께 봅니다.

페이지로 열기 ↗