입력 지연 최적화

입력 지연이 무엇인지 알아보고, 더 빠른 상호작용을 위해 이를 줄이는 기술을 알아보세요.

제레미 와그너
제레미 바그너

웹에서의 상호작용은 복잡한 것이며, 모든 종류의 활동이 브라우저에서 발생합니다. 이들 모두의 공통점은 이벤트 콜백이 실행되기 전에 입력 지연이 발생한다는 것입니다. 이 가이드에서는 입력 지연의 정의와 웹사이트 상호작용이 더 빠르게 실행되도록 이를 최소화하는 방법을 알아봅니다.

입력 지연이란 무엇인가요?

입력 지연은 사용자가 페이지와 처음 상호작용(예: 화면 탭, 마우스 클릭, 키 누르기)한 시점부터 상호작용의 이벤트 콜백이 실행되기 시작할 때까지의 시간입니다. 모든 상호작용은 일정량의 입력 지연으로 시작됩니다.

단순화된 입력 지연 시각화 왼쪽에는 마우스 커서 라인 아트가 있고 그 뒤에는 상호작용의 시작을 나타내는 스타버스트가 있습니다. 오른쪽에는 상호작용의 이벤트 핸들러가 실행되기 시작하는 시점을 나타내는 톱니바퀴 라인 아트가 있습니다. 이 사이의 공백은 중괄호를 사용한 입력 지연으로 표시됩니다.
입력 지연의 메커니즘 운영체제에서 입력을 받으면 상호작용이 시작되기 전에 브라우저에 전달해야 합니다. 이 작업은 어느 정도 시간이 걸리며 기존 기본 스레드 작업으로 늘릴 수 있습니다.

어느 정도의 입력 지연은 피할 수 없습니다. 운영 체제가 입력 이벤트를 인식하고 브라우저에 전달하는 데는 항상 어느 정도 시간이 걸립니다. 하지만 이 정도의 입력 지연은 눈에 띄지 않는 경우가 많으며, 페이지 자체에서 발생하는 다른 문제로 인해 입력 지연이 길어질 수 있습니다.

입력 지연에 대해 생각하는 방법

일반적으로 사용자의 기기와 관계없이 웹사이트가 다음 페인트에 대한 상호작용 (INP) 측정항목의 '양호' 기준을 충족할 가능성이 가장 높도록 상호작용의 모든 부분을 최대한 짧게 유지하는 것이 좋습니다. 입력 지연을 계속 점검하는 것은 이 기준을 충족하는 한 방법일 뿐입니다.

최초 입력 반응 시간 (FID) 기준점을 살펴보고 입력 지연의 허용치를 확인하고 싶을 수도 있지만, FID의 '양호' 기준점은 100밀리초 이하입니다. 이 기준을 초과하면 입력 지연에만 INP에 예산의 절반이 할당됩니다. 이는 상호작용에 이벤트 콜백을 실행하고 브라우저가 다음 프레임을 그리는 데 시간이 필요하다는 점을 고려할 때 권장하지 않습니다.

INP의 '양호' 임곗값을 충족하려면 가능한 가장 짧은 입력 지연을 목표로 해야 하지만 완전히 제거할 수는 없습니다. 사용자가 페이지와 상호작용을 시도하는 동안 기본 스레드가 과도하게 실행되지 않는 한 입력 지연은 문제를 피할 수 있을 만큼 짧아야 합니다.

입력 지연을 최소화하는 방법

앞서 언급했듯이 일부 입력 지연은 피할 수 없지만, 어느 정도의 입력 지연은 피할 수 있습니다. 긴 입력 지연으로 어려움을 겪는 경우 고려할 사항은 다음과 같습니다.

과도한 기본 스레드 작업을 시작하는 반복 타이머 피하기

자바스크립트에서 입력 지연에 영향을 미칠 수 있는 타이머 함수에는 setTimeoutsetInterval 두 가지가 일반적으로 사용됩니다. 이 둘의 차이점은 setTimeout가 지정된 시간 후에 실행할 콜백을 예약한다는 것입니다. 반면 setIntervaln밀리초마다 영구적으로 실행되거나 타이머가 clearInterval로 중지될 때까지 실행되도록 콜백을 예약합니다.

setTimeout는 그 자체로는 문제가 되지 않으며, 실제로 장기적 작업을 방지하는 데 도움이 될 수 있습니다. 그러나 시간 초과가 발생하는 시점 및 시간 제한 콜백이 실행될 때 사용자가 페이지와 상호작용하려고 시도하는지 여부에 따라 다릅니다.

또한 setTimeout는 루프에서 또는 재귀적으로 실행할 수 있으며, 이때 setInterval와 비슷한 방식으로 작동합니다. 단, 이전 반복이 완료될 때까지 다음 반복을 예약하지 않는 것이 좋습니다. 즉, setTimeout가 호출될 때마다 루프가 기본 스레드에 양보되지만 콜백이 과도한 작업을 실행하지 않도록 주의해야 합니다.

setInterval는 일정한 간격으로 콜백을 실행하므로 상호작용에 방해가 될 가능성이 훨씬 커집니다. 그 이유는 사용자 상호작용을 방해할 수 있는 일회성 콜백인 setTimeout 호출의 단일 인스턴스와 달리 setInterval의 반복적인 특성으로 인해 상호작용을 방해할 가능성이 훨씬 높아져 상호작용의 입력 지연이 늘어나기 때문입니다.

입력 지연을 보여주는 Chrome DevTools의 성능 프로파일러 스크린샷 타이머 함수에 의해 실행되는 작업은 사용자가 클릭 상호작용을 시작하기 직전에 발생합니다. 하지만 타이머가 입력 지연을 연장하여 상호작용의 이벤트 콜백이 그렇지 않은 경우보다 늦게 실행됩니다.
Chrome DevTools의 성능 패널에 설명된 대로 입력 지연에 영향을 주는 이전 setInterval 호출에서 등록된 타이머입니다. 추가된 입력 지연으로 인해 상호작용의 이벤트 콜백이 그렇지 않은 경우보다 늦게 실행됩니다.

타이머가 퍼스트 파티 코드로 발생하는 경우 이를 제어할 수 있습니다. 그것이 필요한지 평가하거나 가능한 한 적게 하기 위해 최선을 다하세요. 그러나 서드 파티 스크립트의 타이머는 다른 이야기입니다. 사용자는 서드 파티 스크립트의 기능을 제어할 수 없는 경우가 많으며, 서드 파티 코드의 성능 문제를 해결하려면 이해관계자와 협력하여 지정된 서드 파티 스크립트가 필요한지 확인해야 하는 경우가 많습니다. 그런 경우 서드 파티 스크립트 공급업체에 문의하여 웹사이트에서 발생할 수 있는 성능 문제를 해결하기 위해 취할 수 있는 조치를 결정합니다.

긴 작업 피하기

긴 입력 지연을 완화하는 한 가지 방법은 긴 작업을 피하는 것입니다. 상호작용 중에 기본 스레드를 차단하는 기본 스레드 작업이 과도하게 있으면 긴 작업이 완료되기 전에 입력 지연이 추가로 발생합니다.

작업의 입력 지연 시간이 얼마나 길어지는지를 시각화한 것입니다. 맨 위에서, 상호작용은 하나의 긴 작업이 실행된 직후에 발생하므로 상당한 입력 지연이 발생하여 이벤트 콜백이 실제보다 훨씬 늦게 실행됩니다. 맨 아래에서는 상호작용이 거의 동시에 발생하지만, 긴 작업은 양보를 통해 여러 개의 작은 작업으로 나뉘기 때문에 상호작용의 이벤트 콜백이 훨씬 더 빨리 실행될 수 있습니다.
작업이 너무 길고 브라우저가 상호작용에 빠르게 반응하지 못할 때 더 긴 작업이 더 작은 태스크로 나뉘어 발생하는 경우와 비교하여 어떤 상호작용이 발생하는지 시각화합니다.

작업에서 하는 작업의 양을 최소화하고 항상 기본 스레드에서 가능한 한 적은 작업을 하도록 노력해야 하는 것 외에도 장기 작업을 분할하여 사용자 입력에 대한 응답성을 개선할 수 있습니다.

상호작용 중복에 유의

INP 최적화에서 특히 어려운 부분은 중복된 상호작용이 있는 경우입니다. 상호작용 중복이란 한 요소와 상호작용한 후 첫 상호작용에서 다음 프레임을 렌더링하기 전에 페이지와 다른 상호작용을 하는 것을 의미합니다.

작업이 겹쳐서 긴 입력 지연이 발생할 수 있는 경우를 묘사 이 그림에서는 클릭 상호작용이 키 누름 상호작용과 겹쳐져 키다운 상호작용의 입력 지연이 증가합니다.
Chrome DevTools의 성능 프로파일러에서 동시 실행되는 두 가지 상호작용을 시각화합니다. 최초 클릭 상호작용에서 렌더링 작업으로 인해 이후 키보드 상호작용에 대한 입력 지연이 발생합니다.

상호작용 중복의 원인은 사용자가 단기간에 많은 상호작용을 한 것만큼 간단할 수도 있습니다. 이는 사용자가 양식 입력란에 입력할 때 발생할 수 있는데, 매우 짧은 시간에 많은 키보드 상호작용이 발생할 수 있습니다. 백엔드로 네트워크 요청이 이루어지는 자동완성 필드의 일반적인 경우와 같이 키 이벤트에 대한 작업이 특히 많은 경우 다음과 같은 몇 가지 옵션을 사용할 수 있습니다.

  • 지정된 기간 동안 이벤트 콜백이 실행되는 횟수를 제한하려면 입력을 디바운싱하는 것이 좋습니다.
  • AbortController를 사용하여 발신 fetch 요청을 취소하여 기본 스레드가 fetch 콜백을 처리할 때 혼잡하지 않도록 합니다. 참고: AbortController 인스턴스의 signal 속성을 사용하여 이벤트를 취소할 수도 있습니다.

중복된 상호작용으로 인해 입력 지연이 늘어나는 또 다른 원인은 비용이 많이 드는 애니메이션일 수 있습니다. 특히 JavaScript의 애니메이션은 requestAnimationFrame 호출을 많이 실행하여 사용자 상호작용을 방해할 수 있습니다. 이 문제를 해결하려면 잠재적으로 비용이 많이 들 수 있는 애니메이션 프레임이 큐에 추가되는 것을 방지하기 위해 가능한 한 CSS 애니메이션을 사용하세요. 하지만 이렇게 할 경우 합성되지 않은 애니메이션은 피해야 합니다. 그러면 애니메이션이 기본 스레드가 아닌 GPU 및 컴포지터 스레드에서 주로 실행됩니다.

결론

입력 지연은 상호작용이 실행되는 데 걸리는 시간의 대부분을 나타내지 않을 수 있지만 상호작용의 모든 부분에 소요되는 시간이 줄어들고 있다는 점을 이해하는 것이 중요합니다. 긴 입력 지연이 관찰되면 이를 줄일 기회가 있습니다. 반복되는 타이머 콜백을 피하고, 긴 작업을 중단하고, 잠재적인 상호작용 중복을 인지하는 것만으로도 입력 지연을 줄여 웹사이트 사용자가 더 빠르게 상호작용할 수 있습니다.

Unsplash의 히어로 이미지, Erik Mclean