INP는 사용자의 클릭·탭·키 입력이 발생한 뒤 다음 프레임이 그려질 때까지의 상호작용 지연을 폭넓게 반영하는 지표예요. web.dev 기준으로 2024년 3월부터 FID를 대신해 Core Web Vitals의 반응성 지표가 되었고, 좋은 값은 200ms 이하, 나쁨은 500ms 초과예요. 핵심은 첫 입력 대기만이 아니라 이벤트 처리와 렌더링 비용까지 함께 본다는 점이에요.
INP는 ‘사용자가 반응을 체감하는 지연’을 대표값으로 요약한 지표예요.
AI로 생성된 이미지입니다Google은 2024년 3월부터 Core Web Vitals의 반응성 지표를 FID에서 INP로 바꿨어요 [134]. 이 전환의 이유는 단순해요. FID는 첫 입력이 이벤트 핸들러에 도달하기 전까지의 대기만 주로 보여줬지만, INP는 사용자가 상호작용한 시점부터 다음 프레임이 표시될 때까지의 전체 지연을 본다는 점에서 실제 체감과 더 가깝기 때문이에요 [136]. 즉, 버튼을 눌렀는데 메인 스레드가 바빠서 늦게 실행되는 문제뿐 아니라, 실행 뒤 스타일 계산과 레이아웃, 페인트가 늦어지는 문제까지 한 흐름으로 드러내요 [136][141].
평가 기준도 명확해요. web.dev는 좋은 INP를 200ms 이하, 나쁜 INP를 500ms 초과로 설명해요 [135]. 이 범주는 설명용 예시가 아니라 Google이 Core Web Vitals 해석에 사용하는 공식 구간이에요 [135]. 따라서 실무에서는 “초기 입력은 빨랐는데 사용자가 여전히 버벅임을 느낀다”는 상황을 FID보다 INP가 더 잘 잡아낸다고 이해하면 돼요. 특히 검색 자동완성, 장바구니 수량 변경, 필터 패널 토글처럼 상호작용 이후 UI 갱신이 이어지는 화면에서 이 차이가 분명해져요 [136][141].
INP는 개별 상호작용의 전체 지연을 보고, 페이지 수준에서는 대표적인 느린 상호작용을 집계해요.
측정 메커니즘의 핵심은 ‘첫 입력’이 아니라 ‘상호작용’이에요. web.dev에 따르면 INP는 클릭, 탭, 키 입력 같은 상호작용에서 발생한 지연을, 사용자가 행동한 시점부터 다음 프레임이 표시될 때까지 계산해요 [136]. 여기에는 입력 이벤트가 핸들러를 기다리는 시간, 핸들러가 실행되는 시간, 그 결과로 발생한 렌더링 작업이 모두 포함될 수 있어요 [136][141]. 그래서 자바스크립트가 길게 점유한 경우와 DOM 변경 뒤 레이아웃 계산이 무거운 경우가 같은 INP 문제로 나타날 수 있어요 [140][141].
페이지 수준 집계도 FID와 달라요. web.dev는 페이지의 상호작용들 가운데 가장 나쁜 상호작용이 보통 INP 값을 결정하되, 상호작용 수가 많은 페이지에서는 일부 이상치를 다루는 방식이 적용된다고 설명해요 [137]. 중요한 해석 포인트는 “모든 상호작용의 평균”이 아니라 “사용자가 실제로 한 번 크게 느끼는 최악의 지연에 가깝다”는 점이에요 [137]. 즉, 홈 화면의 첫 클릭이 빨라도, 이후 필터 변경이나 모달 열기에서 한 번 크게 막히면 그 경험이 지표에 반영돼요. 이 특성 때문에 INP는 단일 랜딩 액션보다 중간 흐름의 인터랙션 품질을 더 엄격하게 드러내요 [137].
FID와 INP의 차이는 ‘무엇을 놓치지 않느냐’에서 실무적으로 갈려요.
AI로 생성된 이미지입니다| 항목 | FID | INP |
|---|---|---|
| Core Web Vitals 반영 | 2024년 3월 이전 반응성 지표 [134] | 2024년 3월부터 반응성 지표 [134] |
| 측정 초점 | 첫 입력이 처리 시작되기 전 대기 | 상호작용 시작부터 다음 프레임 표시까지의 전체 지연 [136] |
| 포착 가능한 병목 | 메인 스레드 대기 중심 | 이벤트 처리, 스크립트 실행, 렌더링 비용까지 포함 [136][141] |
| 페이지 해석 방식 | 첫 입력 경험에 치우침 | 대표적인 느린 상호작용에 민감 [137] |
| 실무에서 잘 드러나는 문제 | 초기 로드 직후의 입력 지연 | SPA 전환, 필터, 자동완성, 토글 후 갱신 지연 [137][141] |
이 차이는 특히 현대 프런트엔드 구조에서 중요해요. React, Vue, Svelte 같은 UI 계층을 쓰는 2024년 웹앱은 초기 입력보다 상호작용 후 상태 변경과 재렌더링 비용이 더 큰 경우가 많아요. FID는 “클릭이 접수되기까지”를 주로 보여줬다면, INP는 “클릭 후 화면이 바뀌어 사용자가 결과를 볼 수 있을 때까지”를 더 폭넓게 포착해요 [136]. 그래서 팀이 FID에서 양호 판정을 받았어도, 사용자는 드롭다운 열기나 탭 전환에서 느림을 경험할 수 있었고, INP는 그 간극을 메워줘요 [136][141].
INP 개선은 자바스크립트 장기 작업과 렌더링 비용을 상호작용 단위로 분해하는 작업이에요.
AI로 생성된 이미지입니다진단의 출발점은 Chrome DevTools Performance 패널이에요. web.dev는 INP 문제를 찾을 때 긴 작업, 과도한 스크립트 실행, 렌더링 작업, 레이아웃 시프트를 프로파일링하라고 권해요 [138]. 여기서 중요한 것은 “느린 페이지”가 아니라 “느린 상호작용”을 잡는 거예요. 예를 들어 필터 버튼 클릭 직후 메인 스레드에 200ms 넘는 작업이 붙어 있다면, 그 작업을 쪼개거나 비핵심 작업을 뒤로 미루는 것이 첫 번째 처방이 돼요 [138][140]. DOM이 크고 스타일 재계산이 자주 일어나면, 이벤트 핸들러를 줄여도 INP가 잘 내려가지 않을 수 있으므로 렌더링 비용도 같이 봐야 해요 [141].
// 브라우저 현장 진단용 예시예요.
// INP 자체를 직접 계산하는 완전한 구현이 아니라,
// 긴 프레임과 상호작용 지연을 관찰해 원인 후보를 수집하는 코드예요.
const supportsPO = 'PerformanceObserver' in window;
if (supportsPO) {
try {
const eventObserver = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// 일부 브라우저에서는 duration, interactionId 등을 제공해요.
if (entry.duration > 40) {
console.log('[event]', entry.name, {
startTime: Math.round(entry.startTime),
duration: Math.round(entry.duration),
interactionId: entry.interactionId
});
}
}
});
eventObserver.observe({ type: 'event', buffered: true, durationThreshold: 16 });
} catch (e) {
console.log('event observer not supported', e.message);
}
try {
const lofObserver = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log('[long-animation-frame]', {
startTime: Math.round(entry.startTime),
duration: Math.round(entry.duration)
});
}
});
lofObserver.observe({ type: 'long-animation-frame', buffered: true });
} catch (e) {
console.log('LoAF not supported', e.message);
}
}
위 코드는 INP 값을 공식 집계하는 스니펫이 아니라, 현장에서 어떤 상호작용과 어떤 긴 프레임이 함께 발생하는지 연결해 보는 진단용 도구예요 [139]. web.dev는 Long Animation Frames API와 PerformanceObserver를 활용해 필드에서 긴 프레임과 상호작용 지연을 드러낼 수 있다고 설명해요 [139]. 다만 event 엔트리만으로 곧바로 INP를 계산한다고 이해하면 안 돼요. 실제 INP 해석에는 브라우저의 상호작용 그룹화와 페이지 수준 대표값 집계가 관여하므로, 이 코드는 “원인 후보를 좁히는 관측”에 더 가깝다고 보는 편이 정확해요 [137][139].
INP 최적화에서 가장 흔한 실패는 스크립트만 줄이고 렌더링 병목을 남겨두는 일이에요.
web.dev가 반복해서 강조하는 개선 축은 두 가지예요. 첫째는 상호작용 중 자바스크립트 작업을 줄이는 것이고, 둘째는 DOM과 렌더링 비용을 줄이는 것이에요 [140][141]. 첫 번째는 긴 작업을 분할하고 비핵심 작업을 지연시키는 방식으로 접근해요 [140]. 두 번째는 DOM을 더 작게 유지하고, 비싼 스타일 재계산과 레이아웃 재계산을 피하는 방식으로 접근해요 [141]. 둘 중 하나만 고치면 INP가 남는 이유는, INP가 이벤트 대기와 실행뿐 아니라 다음 프레임 표시 전의 렌더링 비용까지 본다는 구조 자체에 있어요 [136][141].
Chrome DevTools Performance 패널로 느린 상호작용 하나를 녹화해요 [138]. 클릭, 탭, 키 입력 직후 메인 스레드에 긴 작업이 있는지 먼저 확인해요 [138].
긴 스크립트 실행이 보이면 작업을 잘게 나누고, 사용자에게 바로 보이지 않는 로깅·프리페치·후처리는 상호작용 뒤로 미뤄요 [140].
스크립트를 줄였는데도 느리면 스타일 계산, 레이아웃, 페인트 구간을 확인해요 [138]. DOM 변경 범위를 줄이고, 상호작용마다 큰 영역이 다시 계산되지 않도록 구조를 바꿔요 [141].
필드에서는 PerformanceObserver와 Long Animation Frames API로 어떤 상호작용이 긴 프레임과 함께 나타나는지 수집해요 [139].
최종 평가는 페이지의 대표적인 느린 상호작용에 좌우되므로, 첫 클릭만이 아니라 사용 흐름 중간의 필터·토글·모달·자동완성도 반드시 테스트해요 [137].
실무에서 특히 놓치기 쉬운 지점은 “중간 상호작용”이에요. 페이지 로드 직후에는 리소스 최적화에 집중하지만, 사용자가 3번째나 4번째 행동을 할 때는 누적된 상태 변경, 커진 DOM, 반복된 레이아웃 계산이 더 큰 비용을 만들 수 있어요 [137][141]. INP가 FID보다 실사용 반응성을 더 잘 보여주는 이유도 바로 여기에 있어요. 사용자가 실제 세션에서 겪는 가장 나쁜 순간을 더 잘 포착하므로, 팀이 성능 예산을 어디에 써야 하는지 우선순위를 분명하게 만들어 줘요 [137].
FAQ
INP가 좋으면 모든 상호작용이 빠르다고 봐도 되나요?
꼭 그렇지는 않아요. web.dev 설명처럼 INP는 페이지의 대표적인 느린 상호작용에 민감한 지표라서 [137], 분포 전체를 대신하진 않아요. 다만 사용자가 강하게 느끼는 최악 구간을 찾는 데는 유용해요.
왜 FID로는 괜찮았는데 INP로는 문제가 드러나나요?
FID는 첫 입력 전 대기를 주로 봤고, INP는 상호작용 이후 스크립트 실행과 렌더링까지 함께 보기 때문이에요 [136]. 그래서 입력 접수는 빨라도 UI 반영이 늦는 앱에서 차이가 커져요.
INP가 200ms를 넘으면 바로 문제라고 판단해야 하나요?
web.dev 기준으로 200ms 이하는 좋음, 500ms 초과는 나쁨이에요 [135]. 200ms를 조금 넘는다고 무조건 장애는 아니지만, 반복적으로 200ms를 넘는 흐름이 있다면 상호작용 단위 진단을 시작하는 신호로 보는 편이 좋아요.
필드에서 INP 문제를 찾을 때 무엇을 함께 수집해야 하나요?
web.dev는 PerformanceObserver와 Long Animation Frames API를 활용해 긴 프레임과 상호작용 지연을 함께 보라고 권해요 [139]. 여기에 상호작용 이름, 화면 종류, DOM 변경 규모 같은 맥락을 붙이면 원인 분석이 쉬워져요.
가장 먼저 손대야 할 개선 포인트는 무엇인가요?
대개는 상호작용 직후의 긴 자바스크립트 작업이에요 [140]. 하지만 스크립트를 줄였는데도 개선이 적다면 DOM 크기와 스타일·레이아웃 재계산을 같이 봐야 해요 [141]. INP는 두 영역을 모두 반영하니까요 [136].