페이지 로딩은 빠른데 느리게 느껴지나요? 바로 INP 때문입니다
Lighthouse 리포트는 초록색(정상)입니다. LCP도 괜찮습니다. CLS도 괜찮습니다. 페이지 로딩도 빠릅니다.
그런데 실제 사용자 환경(real-world) 점수는 떨어집니다. 이유를 알 수 없습니다.
문제는 아마도 INP일 것입니다. Interaction to Next Paint(INP)는 2024년 3월에 FID를 대체했습니다. FID는 첫 번째 지연 시간만 측정했지만, INP는 사용자가 페이지에 머무는 동안 발생하는 모든 상호작용을 측정합니다. 그리고 그중 가장 느린 값을 보고합니다.
INP는 로딩 지표가 아닙니다. 응답성(responsiveness) 지표입니다. "클릭하거나 타이핑했을 때, 화면이 바뀔 때까지 얼마나 걸리는가?"라는 질문에 답합니다.
Google은 다음과 같은 기준을 사용합니다:
- 200ms 이하: 좋음(good).
- 500ms 초과: 나쁨(poor).
사이트가 1초 만에 로드되더라도 점수가 낮을 수 있습니다. 빠르게 로드되는 것과 빠르게 응답하는 것은 서로 다른 문제입니다.
Lighthouse 도구는 종종 INP를 놓칩니다. Lighthouse는 버튼을 직접 클릭하지 않기 때문입니다. Lighthouse는 추정치를 제공할 뿐입니다. 따라서 실험실 데이터(lab report)는 초록색인데 실제 필드 데이터(field score)는 빨간색일 수 있습니다.
실제 수치를 확인하려면 다음 코드를 사용하세요:
import { onINP } from 'web-vitals';
onINP(function (metric) {
console.log('INP', metric.value, metric.entries);
});
이 코드는 느린 상호작용과 해당 요소를 로그로 남깁니다.
INP 문제는 메인 스레드가 바쁠 때 발생합니다. JavaScript 작업이 완료될 때까지 브라우저는 응답을 화면에 그릴(paint) 수 없습니다.
주요 원인:
- 클릭할 때마다 실행되는 무거운 이벤트 핸들러.
- 채팅 위젯이나 분석 도구와 같은 서드파티 스크립트.
- 지속적인 DOM 읽기/쓰기로 인한 레이아웃 스래싱(Layout thrashing).
- 프레임워크 하이드레이션(hydration) 작업.
긴 작업을 분할하여 해결하세요. 단계 사이에 브라우저가 숨을 쉴 수 있게 해주세요:
async function onClick() {
doUrgentPart();
await yieldToMain();
doExpensivePart();
}
yieldToMain을 사용하여 느린 작업이 시작되기 전에 브라우저가 UI를 그릴 수 있도록 하세요.
기타 해결 방법:
- 즉시 필요하지 않은 스크립트는 지연(defer)시키세요.
- 서드파티 위젯을 점검하세요.
- 무거운 핸들러에 디바운스(debounce)를 적용하세요.
- DOM 읽기 및 쓰기를 일괄 처리(batch)하세요.
실제 점수가 낮다면 LCP만 들여다보지 마세요. 대신 상호작용을 측정하세요.
Source: https://dev.to/lamas51/your-page-loads-fast-but-still-feels-slow-its-inp-not-load-time-2gkn