93%가 통과하던 지표
FID 기준으로 모바일 사이트의 93%가 "good"이었다. 웹이 그만큼 빨라서가 아니었다. 같은 시점에 INP로 다시 재보니 65%만 통과했다. Chrome 팀이 INP 승격을 발표하면서 직접 밝힌 숫자다.
웹은 하루도 바뀌지 않았다. 재는 방식만 바꿨는데 28%p가 사라졌다.
93%가 통과하면 변별력이 없다. 통과했다는 사실이 아무것도 알려주지 않는다. 개발자 입장에서는 더 나쁘다. 통과로 표시되니 고칠 이유가 없어진다.
결함은 이름에 다 적혀 있었다
Chrome 팀이 정리한 FID의 한계는 두 개인데 공교롭게도 이름 안에 그대로 들어 있다. First Input과 Delay다.
먼저 First Input. 사용자는 페이지가 열려 있는 동안 수십 번 클릭하는데 FID는 첫 번째 하나만 본다. 첫 클릭이 그 뒤의 모든 클릭을 대표한다는 보장은 어디에도 없다. 오히려 첫 클릭은 페이지가 막 뜬 직후라 아직 무거운 스크립트가 다 붙기 전인 경우가 많다.
그리고 Delay. 브라우저가 이벤트 핸들러를 실행하기 시작할 때까지의 대기 시간만 잰다. 핸들러가 실제로 무슨 일을 하는지, 그 결과가 화면에 언제 그려지는지는 세지 않는다.
이 둘이 겹치면 놓치는 범위가 커진다. 클릭 핸들러가 메인 스레드를 400ms 붙잡고 있어도 FID 값은 좋게 나온다. 입력 지연이 10ms였다면 FID는 그냥 10ms다. 사용자가 버튼을 누르고 0.4초를 멍하니 기다린 사실은 어디에도 기록되지 않는다.
INP는 세 구간을 전부 센다. 입력 지연, 핸들러가 도는 시간, 그리고 그 결과로 다음 프레임이 그려지기까지의 지연이다. 클릭부터 화면이 바뀔 때까지를 하나의 값으로 잰다. 200ms 이하면 good, 500ms를 넘으면 poor고, 평균이 아니라 75 퍼센타일로 판정한다.
잴 수 있는 걸 쟀다
FID를 만든 사람들이 이걸 몰랐을 리는 없다. 나는 측정이 그만큼 복잡했기 때문이라고 본다.
Core Web Vitals는 실험실 수치가 아니라 필드 데이터다. CrUX가 전 세계 크롬 사용자의 실제 방문에서 값을 수집한다. 그러려면 측정이 간단해야 한다. 첫 입력 하나만 기록하면 페이지당 한 번이면 끝나고, 지연만 재면 타임스탬프 두 개를 빼면 된다. 반면 모든 상호작용의 전 구간을 추적해서 최악값을 뽑으려면 훨씬 복잡해진다. 그때 기준으로는 부담이 컸다.
그러니까 FID는 중요한 걸 잰 지표가 아니라 잴 수 있는 걸 잰 지표였다.
이걸 잘못이라고 부르기는 좀 그렇다. 순서 문제에 가깝다. 없는 것보다 나은 지표를 먼저 쓰다가, 제대로 잴 수 있게 되면 바꾼다. 실제로 그렇게 됐다. INP는 2022년 5월 실험적 지표로 공개됐고, 2023년 5월에 승격이 예고됐다. 그리고 2024년 3월 12일 FID를 대체했다.
지표를 바꾸자 모바일만 떨어졌다
Web Almanac 2024를 보면 이 교체가 얼마나 큰 일이었는지 보인다. 모바일에서 Core Web Vitals 세 지표를 모두 통과한 사이트 비율이 FID 기준으로는 48%인데 INP 기준으로는 43%다. 5%p가 빠졌다.
그런데 데스크톱은 FID로 재나 INP로 재나 54%로 똑같다.
그러니까 INP가 문제를 새로 만든 게 아니다. 저사양 안드로이드에서 무거운 자바스크립트가 메인 스레드를 붙잡는 상황은 원래 있었고 데스크톱에서는 원래 덜했다. FID는 그 격차를 못 봤고 INP는 봤다. 지표를 바꾸자 이미 있던 격차가 숫자에 드러났을 뿐이다.
숫자는 올랐다, 다만 지표 때문만은 아니다
여기서 끝났으면 그냥 지표 교체 이야기다. 그런데 그 뒤로 숫자가 움직였다.
모바일 INP good 비율은 2022년 55%, 2023년 64%, 2024년 74%, 2025년 77%로 올랐다. 데스크톱은 97%다.
그런데 이걸 지표 교체의 성과라고 부르기는 어렵다. INP가 Core Web Vital이 된 건 2024년 3월인데, 그 전인 2022년에서 2023년 사이에 이미 9%p가 올랐다. 정식 지표가 되기 전부터 오르고 있었다는 뜻이다. 오히려 정식 지표가 된 뒤인 2024년에서 2025년 사이에는 3%p 오르는 데 그쳤다.
대신 순위 구간별로 나눠 보면 다르다. 트래픽 상위 1,000개 사이트의 모바일 INP good 비율은 2024년 53%에서 2025년 63%로 올랐다. 전체가 3%p 오르는 동안 이 집단만 10%p 올랐고, 모든 순위 구간 중 개선폭이 가장 크다.

그런데 같은 그래프의 다른 줄을 보면 상위 1,000개의 63%는 전체 평균 77%보다 14%p 낮다. 인기 있는 사이트일수록 INP가 나쁘다. 광고, 추적 스크립트, 개인화, A/B 테스트가 전부 메인 스레드에 얹혀 있으니 이상한 일도 아니다.
정리하면 이렇다. 웹 전체는 지표를 바꾸기 전부터 빨라지고 있었다. 지표를 바꾼 뒤에는 검색 순위에 민감한 사이트들만 크게 움직였다. 제일 무겁고 제일 고치기 어려운 쪽이 가장 많이 고쳤는데도 아직 평균에 못 미친다.
지표가 API를 만들었다
INP가 Core Web Vital이 되면서 조언 하나가 관행으로 굳었다. 긴 작업을 쪼개서 중간중간 메인 스레드를 브라우저에 돌려주라는 것이다.
예전부터 쓰던 방법은 setTimeout(fn, 0)이었는데 문제가 있었다. 넘긴 나머지 작업이 큐 맨 뒤로 가서 그사이 끼어든 다른 작업들에 밀린다. 양보한 쪽이 오히려 더 늦어진다.
그래서 새 API가 나왔다. scheduler.yield()다.
async function applyFilters(items) {
for (const step of [parse, filter, sort, render]) {
step(items);
await scheduler.yield();
}
}await 지점마다 브라우저가 대기 중인 클릭이나 입력을 처리할 틈이 생긴다. 그러면서도 이어지는 작업은 큐 앞쪽으로 들어가서 뒤로 밀리지 않는다. 크롬 129와 엣지 129, 파이어폭스 142가 지원하고 사파리는 아직 지원하지 않는다. 그래서 Baseline은 아니다.
연표를 맞춰보면 순서가 분명하다. 2023년 5월에 INP 승격이 예고됐고, 석 달 뒤인 8월에 scheduler.yield 오리진 트라이얼이 시작됐다. Chrome 팀은 그 발표문에서 INP가 FID를 대체한다는 것을 이유로 들었다. 2024년 3월 INP가 정식 지표가 됐고, 9월에 크롬 129에 정식 탑재됐다.
지표가 예고되자 최적화 관행이 바뀌었고, 그 관행을 위한 API가 브라우저에 들어왔다. 지표가 API를 앞당긴 셈이다.
재지 않으면 문제도 없다
굿하트의 법칙이라는 말이 있다. 어떤 수치를 목표로 삼는 순간 사람들이 그 수치를 올리는 쪽으로만 움직이기 때문에, 결국 그 수치로는 원래 알고 싶던 걸 알 수 없게 된다는 뜻이다.
FID는 이보다 한 단계 앞에서 어긋났다. 목표가 되면서 망가진 게 아니라 처음부터 원하는 걸 재지 않았다. 93%가 통과하는 동안 실제 반응성이 어떤지는 아무도 알 수 없었다.
그런데 굿하트의 법칙은 반대 방향으로도 성립한다. 목표가 되지 않는 측정은 아무것도 바꾸지 못한다.
TTFB와 FCP가 그렇다. 둘 다 로딩이 얼마나 빠른지 보여주는 값이고 web.dev도 그렇게 적어놨지만 Core Web Vitals는 아니다. LCP를 진단하는 보조 지표로 분류된다. 그래서 대시보드에는 뜨지만 분기 목표가 되지는 않는다.
문서에 같은 중요도라고 적혀 있어도 랭킹에 걸렸느냐 아니냐에 따라 사람들이 움직이는 게 다르다.
무엇을 재느냐가 무엇을 고칠지 정한다
FID 시절에도 클릭 후 400ms는 똑같이 느렸다. 그걸 재는 지표가 없었을 뿐이다.
그렇게 보면 지금 우리가 손대지 않는 것들도 다시 볼 만하다. 나쁘지 않아서 안 고치는 게 아니라, 아직 아무도 그걸 재지 않아서 눈에 안 들어오는 것일 수 있다. 스크롤이 끊기는 구간, 애니메이션이 튀는 프레임, 입력하고 글자가 뜨기까지의 지연 같은 것들 말이다. 이 중에 무엇이 다음 지표가 되느냐가 앞으로 몇 년치 작업 목록을 정한다.
어떤 지표를 쓰느냐는 측정 방법을 고르는 문제로 끝나지 않는다. 무엇을 고칠지 정하는 문제이기도 하다.
참고 자료
- Chrome 팀, Advancing Interaction to Next Paint
- Chrome 팀, Interaction to Next Paint becomes a Core Web Vital on March 12
- web.dev, Interaction to Next Paint (INP)
- web.dev, Web Vitals
- HTTP Archive, Web Almanac 2024: Performance
- HTTP Archive, Web Almanac 2025: Performance
- Chrome for Developers, Introducing the scheduler.yield origin trial
- Chrome for Developers, Use scheduler.yield() to break up long tasks