다음 페인트에 대한 상호작용(Interaction to Next Paint, INP)


원문: Jeremy Wagner, https://web.dev/inp/


다음 페인트에 대한 상호작용(Interaction to Next Paint, INP)은 응답성을 평가하는 실험적인 필드 메트릭이다. INP는 전체 페이지 라이프 사이클동안 일어난 모든 상호작용에 대한 지연을 기록한다. 이러한 상호작용은 가장 높은 값(또는 많은 상호 작용이 있는 페이지의 경우 가장 높은 값에 가까운 값)이 페이지의 INP로 기록된다. INP가 낮다면 해당 페이지가 항상 안정적으로 응답할 수 있다는 걸 보장한다.

응답성(페이지가 사용자의 입력에 얼마나 빨리 응답하는지)은 사용자 경험에 매우 중요하다. Chrome 사용 데이터에 따르면 사용자 시간의 대략 90%가 페이지가 로드된 에 사용되므로 응답성을 신중하게 측정하는 것이 중요하다. 특히 웹 사이트가 상호작용을 제공하기 위해 자바스크립트에 의존하는 경우가 많아짐에 따라 더 중요해졌다. 이것이 INP가 측정하는 것이며, 이는 페이지의 전체 라이프사이클을 포함한다.

응답성이 좋을 때 페이지는 상호작용에 빠르게 응답한다. 앱이 상호작용에 응답할 때 사용자 인터페이스의 변경사항은 시각적 피드백의 결과이다. 시각적 피드백은 예를 들어 온라인 쇼핑몰 장바구니에 추가하도록 요청한 항목이 실제로 추가되고 있는지, 로그인 폼에 입력한 정보가 서버에서 인증되는지, 모바일 메뉴가 열렸는지 등을 알려준다.

다음 비디오에서 오른쪽 예시는 네트워크에서 이미지를 가져오고 있다는 즉각적인 시각적 피드백을 제공한다. 이러한 시각적 피드백은 상호작용의 결과를 전달하는 것이 중요하다는 것을 강조한다.

썸네일 갤러리에서 실제 크기 이미지를 로드하는 경우 응답성이 좋은지 나쁜지를 시각적으로 나타낸다. 왼쪽은 실제 크기 이미지를 표시하기 전에 다운로드해야 하기 때문에 응답성이 나쁘고 상당한 지연이 있다. 오른쪽은 이미지를 요청하면 로딩 인디케이터가 나타나고, 그 후 요청된 이미지로 교체되기 때문에 응답성이 좋다.

이 글에서는 INP가 동작하는 방법, INP를 측정하는 방법, 개선하는 방법에 대해 설명한다.좋은 사용자 경험을 위해서 좋은 응답성은 필수적이다.

INP란?

INP는 사용자가 페이지를 방문했을 때 발생하는 단일 상호작용 중 가장 긴 것을 선택하여 페이지의 전반적인 상호작용이 지연된 시간을 나타내는 것을 목표로 하는 메트릭이다. 총 50개 미만의 상호작용이 있는 페이지의 경우 INP는 가장 오래 지연되는 상호작용이다. 많은 상호작용이 있는 페이지의 경우 INP는 지연되는 상호작용 중 98번째 백분위수(percentile)로 결정된다.

💡 중요
모든 페이지에서 가장 긴 상호작용이 선택되지 않는 이유에 대해 더 자세히 알고 싶다면 최악의 상호작용 지연 시간을 선택하지 않는 이유 섹션을 참고해라.

상호작용은 동일한 논리적 사용자 제스처동안 일어나는 입력 이벤트의 집합이다. 예를 들어, 터치스크린 기기의 "탭" 상호작용에는 pointerup, pointerdown, click과 같은 여러 이벤트가 포함되며 이러한 모든 이벤트는 전체 상호작용의 지연 시간에 영향을 끼칠 수 있다.

단일 상호작용의 지연 시간은 상호작용의 일부인 어떠한 이벤트 중 가장 긴 단일 지속 시간으로 구성된다. 여기서 지속 시간이란 사용자가 페이지와 상호작용한 시점부터 모든 관련된 이벤트 핸들러가 실행된 후 다음 프레임이 표시될 때까지이다. 지속 시간은 다음 기간들의 합이다.

  • 입력 지연 시간: 사용자가 페이지와 상호작용한 뒤 이벤트 핸들러가 실행될 때까지 걸리는 시간
  • 처리 시간: 관련 이벤트 핸들러에서 코드를 실행하는 데 걸리는 총 시간
  • 표시 지연 시간: 이벤트 핸들러가 실행을 마치고 브라우저가 다음 프레임을 표시하는 데 걸리는 시간

💡 중요
INP가 정확히 어떻게 측정되는지 더 자세히 알고 싶다면 상호작용을 구성하는 것 섹션을 참고해라.

"좋은" INP 값이란?

응답성 메트릭에 "좋다" 또는 "나쁘다"라는 라벨을 붙이는 것은 어렵다. 한편으로는 좋은 응답성을 제공하도록 사용자 경험을 개선하는 것을 장려하고자 한다. 다른 한편으로는 사람들이 사용하는 기기가 제공하는 기능은 상당히 다르다는 사실을 고려해야 하며, 저가형 기기에서 충분히 충족할 수 있는 목표를 선택하여 달성 가능한 기대치를 설정해야 한다.

이러한 점을 염두에 두고, 응답성 메트릭이 광범위한 유스 케이스에 적합해야 한다는 것이 중요하다. 목표에 도달했는지 확인하기 위해 모바일과 데스크탑 기기를 포함하여 기록된 페이지 로드의 75번째 백분위수에서 측정하는 것이 좋은 임계값이다.

  • INP가 200 밀리초 이하인 경우 페이지의 응답성이 좋다.
  • INP가 200 밀리초 초과, 500 밀리초 미만인 경우 페이지의 응답성이 개선될 필요가 있다.
  • INP가 500초 이상인 경우 페이지의 응답성이 나쁘다.

What is a good INP value?

💡 중요
INP는 실험적 메트릭이므로 임계값에 대한 가이드는 메트릭이 미세 조정되며 시간이 지남에 따라 변경될 수 있다. 이 글의 마지막에 있는 CHANGELOG는 변경 사항을 반영하도록 업데이트된다.

상호작용을 구성하는 것

단일 상호작용의 단계. 입력 지연은 입력을 받은 시점부터 발생하며, 메인 스레드에서 작업을 차단하는 등의 요인으로 인해 생길 수 있다. 처리 시간은 상호작용의 이벤트 핸들러가 실행되는 데 걸리는 시간이다. 실행이 끝나면 다음 프레임을 렌더링하고 페인팅하는 데 걸리는 시간인 표시 지연 단계로 들어간다.

페이지와 상호작용을 할 때 브라우저는 체크박스, 라디오 버튼, HTML의 <details> 요소처럼 자바스크립트 없이 동작할 수 있는 상호작용을 제공하기도 하지만, 자바스크립트로 상호작용을 동작하게 하는 경우가 종종 있다. INP에 관한 한, 상호작용은 다음 중 하나로 구성된다.

  • 마우스로 상호작용이 가능한 요소를 클릭한다.
  • 터치스크린 기기에서 상호작용이 가능한 요소를 탭한다.
  • 물리적 또는 화면상의 키보드에서 키를 누른다.

하나의 상호작용은 여러 이벤트로 구성될 수 있다. 예를 들어 키를 한번 누르는 것은 keydownkeyup 이벤트로 이루어진다. 탭은 pointeruppointerdown 이벤트가 포함된다. 모든 상호작용의 이벤트는 논리적 사용자 상호작용의 일부이다.

앞서 말했듯이, 각 상호작용은 입력 지연, 처리 시간, 표시 지연의 3단계로 구성되어 있다. 상호작용과 관련된 이벤트의 콜백 기간은 3단계 전부에 걸쳐 관련된 시간의 총합이다. 논리적 사용자 상호작용에서 가장 지연 시간이 긴 이벤트가 기록된다.

더 복잡한 상호작용을 묘사한 것이다. 상호작용의 첫번째 부분은 사용자가 마우스 버튼을 눌렀을 때 입력을 받지만 마우스 버튼을 떼기 전에 프레임이 렌더링되고 표시된다. 사용자가 마우스 버튼을 떼면 다음 프레임이 그려지기 전에 또다른 일련의 입력 지연, 처리 시간, 표시 지연 단계가 발생해야 한다. 둘 중 가장 긴 것이 상호작용에 대한 지연 시간으로 기록된다.

CLS(Cumulative Layout Shift, 누적 레이아웃 이동)와 마찬가지로 INP는 사용자가 페이지를 떠날 때 계산되어 전체 페이지 라이프 사이클동안 페이지의 전반적인 응답성을 나타내는 단일 값을 결과로써 도출한다. 만약 높은 백분위수의 페이지 상호작용이 빠르게 응답한다면, 이는 모든 낮은 백분위수의 상호작용도 빠르다는 걸 의미한다.

최악의 상호작용 지연 시간을 선택하지 않는 이유

상대적으로 상호작용이 적은 페이지의 경우 최악의 상호작용을 사용하는 것이 좋다. 그러나 모든 웹 페이지가 그렇지는 않다. 일부는 다른 것보다 더 많은 상호작용을 필요로 한다. 예를 들어 블로그나 뉴스 웹사이트에 비해 텍스트 에디터나 비디오 게임 앱은 더 많은 상호작용이 필요하다.

상호작용이 아주 많은 페이지의 경우 최악의 상호작용을 사용하면 잘못 해석될 소지가 있다. 응답성을 우선시하는 웹사이트에서도 가끔 일시적으로 지연 시간이 길어지는 경우가 있기 때문에 이러한 상호작용을 제외해야 한다.

모든 경우에 가장 높은 것은 아니지만 높은 백분위 수에 초점을 맞추면 대부분의 페이지 상호작용이 적시에 응답하는지 여부를 공정하게 평가할 수 있다. 상호작용 수에 따라 선택되는 상호작용 지연 백분위수가 어떻게 달라지는지는 아래 섹션에서 확인할 수 있다.

페이지 상호작용 수에 따른 INP 후보

페이지 상호작용 수 INP로 기록되는 상호작용
1 ~ 49 가장 큰 것
50 ~ 99 두번째로 큰 것
100 ~ 149 세번째로 큰 것
150 ~ 199 네번째로 큰 것
200 ~ 249 다섯번째로 큰 것
250 ~ 299 여섯번째로 큰 것
300 ~ 349 일곱번째로 큰 것
350 ~ 399 여덟번째로 큰 것
400 ~ 449 아홉번째로 큰 것
450+ 열번째로 큰 것

INP이 최초 입력 지연(First Input Delay, FID)과 다른 점

INP는 모든 페이지 상호작용를 고려하는 반면, 최초 입력 지연(First Input Delay, FID)첫번째 상호작용만 처리한다. 또한 이벤트 핸들러의 처리 시간이나 다음 프레임을 표시하는데 걸리는 지연 시간은 측정하지 않고 입력 지연만 측정한다.

FID도 로드 응답성 메트릭이라는 점을 고려했을 때, 로딩 중인 페이지와의 첫번째 상호작용에서 인지할 수 있는 입력 지연이 거의 없었다면 해당 페이지는 좋은 첫인상을 남긴 것이다.

INP는 첫인상 그 이상이다. 페이지가 로드되기 시작했을 때부터 사용자가 페이지를 떠날 때까지 발생할 수 있는 상호작용의 전체 범위를 다룬다. 모든 상호작용을 추출, 분석하여 응답성을 포괄적으로 평가할 수 있다. 이 때문에 응답성 지표로서 INP를 FID보다 더 신뢰할 수 있다.

INP는 페이지의 전체 라이프 사이클동안 지속적으로 변경되고 업데이트되는 메트릭이라는 점에서 누적 레이아웃 이동(Cumulative Layout Shift, CLS)과 비슷하다고 생각하는 것이 가장 좋다. CLS와 마찬가지로 사용자가 페이지를 떠나기 전까지는 INP 값을 기록할 필요가 없다.

사용자가 페이지와 상호작용을 전혀 하지 않는다면?

때때로 페이지가 로드되었지만 상호작용이 한번도 일어나지 않는 경우가 있다. 이는 아래와 같이 여러 가지 이유로 발생할 수 있다.

  • 누군가 페이지를 로드했지만 주의가 산만해져서 한번도 사용하지 않았을 수 있다.
  • 누군가 페이지를 로드하고 스크롤(INP가 고려하지 않는 상호작용)했지만 클릭, 탭, 키 누르기를 하지 않았을 수 있다. 아마 페이지에서 사용자가 찾고자 하는 부분에 도달하는 데 상호작용이 필요하지 않았을 것이다.
  • 페이지와 상호작용하도록 설계되지 않은 봇(예를 들어, 검색 크롤러 또는 헤드리스 브라우저)이 페이지에 접근했을 수 있다.

이러한 경우에는 INP 값이 기록되지 않는다.

INP를 측정하는 방법

INP는 다양한 툴을 이용하여 필드와 (약간의 노력을 기울여서) 에서 측정할 수 있다.

역자: 필드 데이터와 랩 데이터는 다음과 같다.

  • 필드 데이터: 페이지를 방문한 실제 사용자로부터 수집한 데이터
  • 랩 데이터: 기기나 네트워크 환경 등이 미리 설정되어 통제된 환경에서 수집된 데이터

💡 중요
웹사이트의 INP를 측정하는 가장 좋은 방법은 필드에서 실제 사용자로부터 메트릭을 수집하는 것이다. 성능을 평가할 때 랩 데이터에 의존하는 데 익숙하다면 시간을 내어 랩 데이터와 필드 데이터가 다를 수 있는 이유 (및 이와 관련하여 해야할 일)를 읽어보자.

필드 툴

랩 툴

자바스크립트로 INP 측정하기

INP를 측정하기 위해 직접 PerformanceObserver를 작성하는 건 어려울 수 있다. 자바스크립트로 INP를 측정하려면 web-vitals 자바스크립트 라이브러리의 onINP 함수를 사용하는 걸 추천한다. INP 데이터를 가져오는 것은 web-vitals 버전 3(현재 베타)에서만 가능하며 아래의 커맨드로 설치할 수 있다.

npm install web-vitals@next --save

그런 다음 onINP 함수로 페이지의 INP를 얻을 수 있다.

import {onINP} from 'web-vitals';

onINP(({value}) => {
  // 콘솔에 값을 기록하거나 분석 프로그램에 값을 보낼 수 있다.
  console.log(value);
});

web-vitals의 다른 함수들처럼 onINP는 함수를 인자로 받는다. 그리고 사용자가 제공한 함수에 메트릭 데이터를 전달한다. 여기서 수집하거나 추가 분석을 위해 데이터를 엔드포인트로 보낼 수 있다.

onINP에 대한 추가적인 설명은 문서를 참고한다.

❗️경고
필드에서 INP 메트릭을 수집하는 것은 interactionId 속성을 포함하여 Event Timing API를 완전히 지원하는 브라우저에서만 작동한다.

자바스크립트로 직접 INP를 측정하는 것은 까다롭다. 최선의 결과를 얻으려면 web-vitals 자바스크립트 라이브러리를 사용하는 것을 강력히 추천한다. 그러나 페이지에서 가장 긴 상호작용이 어떻게 보이는지 확인하려면 브라우저 개발자 도구의 콘솔에서 아래 자바스크립트 스니펫을 복사 붙여넣기하여 필요에 따라 조정할 수 있다.

콘솔에 상호작용 지연 시간을 기록하기 위한 자바스크립트 스니펫

let maxDuration = 0;

new PerformanceObserver(list => {
  for (const entry of list.getEntries()) {
    // 모든 이벤트 유형을 보이게 하려면 아래 라인을 주석처리한다. (파이어폭스 같은 브라우저에서 유용하다).
    if (!entry.interactionId) continue;

    if (entry.duration > maxDuration) {
      // 가장 긴 INP.
      maxDuration = entry.duration;
      console.log(`[INP] duration: ${entry.duration}, type: ${entry.name}`, entry);
    } else {
      // 가장 긴 상호작용은 아니지만, 이를 확인하고 싶다면 아래 라인을 주석에서 제외한다.
      // console.log(`[Interaction] duration: ${entry.duration}, type: ${entry.name}`, entry);
    }
  }
}).observe({
  type: 'event',
  durationThreshold: 16, // 스펙 상 지원되는 최소값
  buffered: true
});

INP를 개선하는 방법

웹사이트의 INP 값이 "좋은" 응답성 범위를 벗어나는 경우, 자연스럽게 이 값을 개선하기 위해 무엇을 할 수 있을지 알아내고 싶을 것이다. 높은 INP 값은 보통 사용자 상호작용과 동시에 실행될 수 있는 자바스크립트 또는 자바스크립트가 아닌 다른 메인 스레드 작업에 대한 높은 의존도를 나타낸다.

페이지가 시작되는 동안 INP를 개선하기

INP는 페이지 로드 시 중요한 요소가 될 수 있는데, 페이지가 작동하는 데 필요한 상호작용을 제공하는 이벤트 핸들러를 설정하기 위해 자바스크립트를 가져올 때 사용자가 상호작용을 시도할 수 있기 때문이다.

HTTP 아카이브에 따르면 총 차단 시간(Total Blocking Time, TBT)은 FID에 비해 INP와 2배나 더 큰 상관 관계를 보인다. TBT는 랩 메트릭이지만, 랩 툴에서 높은 TBT 값이 관찰되는 경우 필드에서는 그보다 더 높은 INP 값이 관찰될 수도 있다.

페이지 로드 중 응답성을 개선하려면 다음 해결책을 확인해보자.

  • 크롬 개발자도구에서 커버리지 툴을 사용하여 사용하지 않는 코드를 제거한다.
  • 페이지 로드 중에 필요하지 않은 자바스크립트를 지연 로드할 수 있도록 코드 분할이 가능한 곳을 찾는다. 이 때 커버리지 툴이 도움이 될 수 있다.
  • 시작하는 동안 로드하는 느린 써드파티 자바스크립트를 찾는다.
  • 성능 프로파일러를 사용하여 최적화할 수 있는 긴 작업을 찾는다.
  • 자바스크립트가 완료된 후 브라우저 렌더링에 너무 많은 것을 요청하지 않는지 확인한다. 즉, 큰 컴포넌트 트리 리렌더링, 큰 이미지 디코딩, 너무 많고 무거운 CSS 효과 등이 많은지 확인한다.

페이지가 시작된 후 INP를 개선하기

INP는 페이지의 전체 라이프 사이클동안 추출된 입력으로 계산되기 때문에 사이트의 INP는 페이지 시작 일어나는 일에 영향을 받을 수 있다. 만약 이에 해당된다면, 해결책을 찾기 위해 다음과 같은 영역을 조사해야 한다.

CHANGELOG

현재까지는 INP 메트릭에 변경 사항이 생기지 않았다. 만약 변경 사항이 생긴다면 여기 CHANGELOG에 기록된다. 해당 메트릭에 대해 피드백이 있는 경우 web-vitals 피드백 구글 그룹을 통해 전달할 수 있다.