웹 성능의 새로운 기준, INP: FID를 대체한 핵심 지표 최적화 실전 가이드
그동안 우리는 ‘페이지가 얼마나 빨리 뜨는가’에 집중해 왔습니다. 하지만 페이지가 뜬 이후, 버튼을 눌렀는데 한참 뒤에 반응한다면 사용자는 그 사이트를 ‘느리다’고 느낍니다. 구글은 이러한 사용자 경험을 수치화하기 위해 새로운 지표인 **INP(Interaction to Next Paint)**를 도입했습니다.
오늘은 기존 FID의 한계를 넘어선 INP가 무엇인지, 그리고 어떻게 최적화할 수 있는지 알아보겠습니다.
1. FID와 INP, 무엇이 다른가?
과거의 **FID(First Input Delay)**는 사용자의 ‘첫 번째’ 입력에 대한 지연 시간만 측정했습니다. 하지만 INP는 페이지에 머무는 동안 발생하는 ‘모든’ 상호작용을 관찰하고 그중 가장 긴 지연 시간을 대표값으로 설정합니다.
- FID: 첫 클릭만 중요함 (빙산의 일각).
- INP: 클릭, 탭, 키보드 입력 등 전체 여정의 반응성을 측정 (전체 사용자 경험).
2. INP가 발생하는 3가지 단계
사용자가 버튼을 클릭한 순간부터 다음 프레임이 화면에 그려질 때까지의 시간은 크게 세 부분으로 나뉩니다.
- 입력 지연(Input Delay): 메인 스레드가 다른 작업(JS 실행 등)을 하느라 입력을 처리하기 시작할 때까지 걸리는 시간.
- 처리 시간(Processing Time): 이벤트 핸들러(JS 로직)가 실행되는 시간.
- 프레임 표시 지연(Presentation Delay): 렌더링 엔진이 화면을 다시 계산하고 그리는 시간.
3. INP를 낮추기 위한 최적화 전략
INP 점수를 ‘Good(200ms 이하)‘으로 만들기 위해서는 메인 스레드를 비워주는 것이 핵심입니다.
패턴 A: 무거운 작업 쪼개기 (Yielding to Main Thread)
하나의 긴 자바스크립트 작업이 실행 중이면 사용자의 입력이 무시됩니다. setTimeout이나 scheduler.yield()를 사용하여 작업을 작게 쪼개야 합니다.
// Before: 메인 스레드를 오래 점유함
function handleButtonClick() {
doMassiveWork(); // 500ms 소요
showFeedback();
}
// After: 작업을 쪼개서 브라우저에게 렌더링 기회를 줌
async function handleButtonClick() {
// 중요한 UI 업데이트를 먼저 처리
showLoadingState();
// 브라우저에게 제어권을 일시적으로 넘김
await new Promise(resolve => setTimeout(resolve, 0));
// 나머지 무거운 작업 수행
doMassiveWork();
}
패턴 B: 레이아웃 스래싱(Layout Thrashing) 방지
DOM 요소를 수정하고 즉시 크기 정보를 읽는 행위는 브라우저에게 강제 동기 레이아웃을 유발하여 프레임 표시 지연을 늘립니다.
패턴 C: 가벼운 컴포넌트 구조
불필요한 리액트 재렌더링을 줄여 자바스크립트 처리 시간 자체를 단축해야 합니다. 앞서 다룬 React Compiler가 이 단계에서 큰 도움을 줄 수 있습니다.
4. INP 측정 및 모니터링
내 사이트의 INP 점수는 어떻게 확인할 수 있을까요?
- PageSpeed Insights: 실제 사용자 데이터를 기반으로 한 INP 필드 데이터를 제공합니다.
- Web Vitals Extension: 개발자 도구에서 실시간으로 상호작용 지연 시간을 확인할 수 있습니다.
- Lighthouse: 실험실 환경에서의 성능 분석을 제공합니다.
5. 마치며: ‘빠른 로딩’에서 ‘부드러운 반응’으로
SEO와 사용자 유지율을 결정짓는 기준이 바뀌고 있습니다. 이제는 단순히 첫 화면을 빨리 보여주는 것을 넘어, 사용자의 모든 움직임에 민감하게 반응하는 웹사이트를 만들어야 합니다.
여러분의 사이트는 사용자의 클릭에 즉각 대답하고 있나요? 지금 바로 INP 지표를 점검해 보세요.