Early Hints와 함께 서버 분석 시간을 이용해 페이지 로드 속도 향상

서버가 중요한 하위 리소스에 대한 힌트를 브라우저에 보내는 방법을 알아보세요.

켄지 바휴
Kenji Baheux
배리 폴라드
배리 폴라드

사전 힌트란 무엇인가요?

웹사이트는 시간이 지남에 따라 더욱 정교해졌습니다. 따라서 요청된 페이지의 HTML을 생성하기 위해 서버에서 간단한 작업 (예: 데이터베이스에 대한 액세스 또는 원본 서버에 액세스하는 CDN)을 수행해야 하는 경우가 많습니다. 안타깝게도 이러한 '서버 고려 시간'으로 인해 브라우저가 페이지 렌더링을 시작하기 전에 추가 지연 시간이 발생합니다. 실제로 서버가 응답을 준비하는 한 연결은 사실상 유휴 상태가 됩니다.

페이지 로드와 기타 리소스 로드 간의 서버 분석 시간 간격 200밀리초를 보여주는 이미지
조기 힌트 사용 불가: 기본 리소스에 응답할 방법을 결정하기 위해 서버에서 모든 항목이 차단됩니다.

사전 힌트는 최종 응답 전에 예비 HTTP 응답을 전송하는 데 사용되는 HTTP 상태 코드 (103 Early Hints)입니다. 이렇게 하면 서버가 기본 리소스를 생성하는 동안에도 서버가 중요한 하위 리소스 (예: 페이지의 스타일시트, 중요한 자바스크립트) 또는 페이지에서 사용할 가능성이 있는 출처에 대한 힌트를 브라우저에 보낼 수 있습니다. 브라우저는 기본 리소스를 기다리는 동안 이러한 힌트를 사용하여 연결을 준비하고 하위 리소스를 요청할 수 있습니다. 다시 말해, Early Hints는 브라우저가 일부 작업을 미리 실행함으로써 이러한 '서버 사고 시간'을 활용할 수 있도록 하여 페이지 로드 속도를 높여줍니다.

Early Hints를 통해 페이지에서 부분 응답을 전송하는 방식을 보여주는 이미지입니다.
Early Hints를 사용하는 경우: 서버가 최종 응답을 결정하는 동안 리소스 힌트가 포함된 부분 응답을 제공할 수 있음

경우에 따라 최대 콘텐츠 렌더링 시간의 성능 개선은 ShopifyCloudflare에서 관찰한 바와 같이 수백 밀리초에서 몇 밀리초까지 단축될 수 있으며 다음 전과 후 비교에서 알 수 있듯이 최대 1초 더 빠르게 개선될 수 있습니다.

두 사이트 비교
WebPageTest (Moto G4 - DSL)를 사용한 테스트 웹사이트의 Early Hints 비교 전후 비교

사전 힌트 구현

본론으로 들어가기 전에, 서버에서 200 또는 기타 최종 응답을 즉시 보낼 수 있다면 사전 힌트는 유용하지 않습니다. 이러한 상황에서는 기본 응답 (Link rel HTTP 헤더)이나 기본 응답 (<link> 요소)에서 일반 link rel=preload 또는 link rel=preconnect을 사용하는 것이 좋습니다. 서버가 기본 응답을 생성하는 데 시간이 필요한 경우에는 계속 읽어보세요.

사전 힌트를 활용하려면 먼저 인기 방문 페이지, 즉 사용자가 웹사이트를 방문할 때 일반적으로 시작하는 페이지를 파악해야 합니다. 다른 웹사이트를 통해 유입된 사용자가 많다면 홈페이지나 인기 제품 등록정보 페이지일 수도 있습니다. 이러한 진입점이 다른 페이지보다 중요한 이유는 사용자가 웹사이트를 탐색할 때 Early Hints의 유용성이 떨어지기 때문입니다. 즉, 브라우저가 두 번째 또는 세 번째 후속 탐색에서 필요한 모든 하위 리소스를 가질 가능성이 높기 때문입니다. 좋은 첫인상을 남기는 것도 좋습니다.

이제 우선순위가 지정된 방문 페이지 목록을 만들었으므로 다음 단계는 사전 연결 또는 미리 로드 힌트에 적합한 출처 또는 하위 리소스를 첫 번째 근사값으로 식별하는 것입니다. 일반적으로 최대 콘텐츠 렌더링 시간 또는 콘텐츠가 포함된 첫 페인트와 같은 주요 사용자 측정항목에 가장 많이 기여하는 출처 및 하위 리소스가 여기에 해당합니다. 보다 구체적으로 동기식 JavaScript, 스타일시트, 웹 글꼴 등 렌더링 차단 하위 리소스를 찾아보세요. 마찬가지로 주요 사용자 측정항목에 많이 기여하는 하위 리소스를 호스팅하는 출처를 찾습니다. 참고: 기본 리소스가 이미 <link rel=preconnect> 또는 <link rel=preload>를 사용하고 있다면 이러한 출처나 리소스를 사전 힌트 후보로 고려할 수 있습니다. 자세한 내용은 이 도움말을 참고하세요.

두 번째 단계는 더 이상 사용되지 않거나 기본 리소스에서 더 이상 사용하지 않는 리소스 또는 출처에서 사전 힌트를 사용할 위험을 최소화하는 것입니다. 예를 들어 자주 업데이트되고 버전이 관리되는 리소스 (예: example.com/css/main.fa231e9c.css)는 최선의 선택이 아닐 수 있습니다. 이 문제는 사전 힌트에만 국한되지 않으며 rel=preload 또는 rel=preconnect 링크가 있을 수 있는 모든 위치에 적용됩니다. 자동화 또는 템플릿에 가장 적합한 세부정보 유형입니다. 예를 들어 수동 프로세스에서는 link rel=preload와 리소스를 사용하는 실제 HTML 태그 간에 해시 또는 버전 URL이 일치하지 않을 가능성이 높습니다.

다음 흐름을 예로 들어 보겠습니다.

GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]

서버는 main.abcd100.css가 필요할 것으로 예측하고 사전 힌트를 통해 미리 로드할 것을 제안합니다.

103 Early Hints
Link: </main.abcd100.css>; rel=preload; as=style
[...]

잠시 후 연결된 CSS가 포함된 웹페이지가 게재됩니다. 안타깝게도 이 CSS 리소스는 자주 업데이트되며 기본 리소스는 이미 예측된 CSS 리소스 (abcd100)보다 다섯 가지 버전 (abcd105) 앞서 있습니다.

200 OK
[...]
<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.abcd105.css">

일반적으로 상당히 안정적이고 기본 리소스의 결과와 크게 독립된 리소스와 출처를 목표로 합니다. 필요한 경우, 주요 리소스를 두 개로 분할하는 것이 좋습니다. 하나는 사전 힌트와 함께 사용하도록 설계된 안정적인 부분이고, 다른 하나는 기본 리소스를 브라우저에서 수신한 후에 가져와야 하는 좀 더 동적입니다.

<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.css">
   <link rel="stylesheet" href="/experimental.3eab3290.css">

마지막으로, 서버 측에서 사전 힌트를 지원하는 것으로 알려진 브라우저에서 보낸 기본 리소스 요청을 찾아 103개의 사전 힌트로 즉시 응답합니다. 103 응답에 관련 사전 연결 및 미리 로드 힌트를 포함합니다. 기본 리소스가 준비되면 일반적인 응답을 보냅니다 (예: 성공한 경우 200 OK). 이전 버전과의 호환성을 위해 최종 응답에 Link HTTP 헤더도 포함하는 것이 좋습니다. 기본 리소스를 생성하는 과정에서 명확하게 드러난 중요한 리소스로 보강할 수도 있습니다 (예: '2로 분할' 제안을 따르는 경우 키 리소스의 동적 부분). 다음과 같이 표시됩니다.

GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]
103 Early Hints
Link: <https://fonts.google.com>; rel=preconnect
Link: </main.css>; rel=preload; as=style
Link: </common.js>; rel=preload; as=script

잠시 후:

200 OK
Content-Length: 7531
Content-Type: text/html; charset=UTF-8
Content-encoding: br
Link: <https://fonts.google.com>; rel=preconnect
Link: </main.css>; rel=preload; as=style
Link: </common.js>; rel=preload; as=script
Link: </experimental.3eab3290.css>; rel=preload; as=style
<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.css">
   <link rel="stylesheet" href="/experimental.3eab3290.css">
   <script src="/common.js"></script>
   <link rel="preconnect" href="https://fonts.googleapis.com">

브라우저 지원

103 Early Hints는 모든 주요 브라우저에서 지원되지만, 사전 힌트에서 전송할 수 있는 지시어는 브라우저마다 다릅니다.

사전 연결 지원:

브라우저 지원

  • 103
  • 103
  • 120
  • 17

미리 로드 지원:

브라우저 지원

  • 103
  • 103
  • x

서버 지원

다음은 널리 사용되는 OSS HTTP 서버 소프트웨어에서 Early Hints에 대한 지원 수준을 요약한 것입니다.

Early Hints 사용 설정하기

다음 CDN 또는 플랫폼 중 하나를 사용하는 경우 사전 힌트를 수동으로 구현하지 않아도 됩니다. 솔루션 제공업체의 온라인 문서를 참조하여 Early Hints를 지원하는지 확인하거나 여기에서 일부 예시 목록을 참조하세요.

사전 힌트를 지원하지 않는 클라이언트 문제 방지

100 범위의 정보 제공 HTTP 응답은 HTTP 표준의 일부이지만, 103 얼리 힌트(Early Hints)가 출시되기 전에는 일반 웹 탐색에 거의 사용되지 않았기 때문에 일부 오래된 클라이언트나 봇의 경우 이러한 부분에서 어려움을 겪을 수 있습니다.

sec-fetch-mode: navigate HTTP 요청 헤더를 전송하는 클라이언트에 대한 응답으로 103 사전 힌트를 내보낼 때만 후속 응답 대기를 이해하는 최신 클라이언트에 대해서만 이러한 힌트가 전송되도록 해야 합니다. 또한 사전 힌트는 탐색 요청에서만 지원되므로 (현재 제한사항 참고) 다른 요청에서 이러한 정보를 불필요하게 전송하지 않아도 되는 부가적인 이점이 있습니다.

또한 사전 힌트는 HTTP/2 또는 HTTP/3 연결을 통해서만 전송하는 것이 좋습니다.

고급 패턴

주요 방문 페이지에 조기 힌트를 완전히 적용했는데 더 많은 기회를 찾고 있다면 다음과 같은 고급 패턴을 확인해 보시기 바랍니다.

일반적인 사용자 여정의 일부로 n번째 페이지 요청을 하는 방문자의 경우, 페이지 하위에 있는 콘텐츠에 맞춰 사전 힌트를 조정하는 것이 좋습니다. 즉, 우선순위가 낮은 리소스에는 조기 힌트를 사용하는 것이 좋습니다. 우선순위가 높고 렌더링을 차단하는 하위 리소스 또는 출처에 집중하는 것이 좋다는 점을 고려하면 이는 직관적이지 않을 수 있습니다. 그러나 방문자가 한동안 탐색하는 동안에는 브라우저에 이미 중요한 리소스가 모두 있을 가능성이 매우 큽니다. 그 이후에는 우선순위가 낮은 리소스로 주의를 돌리는 것이 좋을 수 있습니다. 예를 들어, 사전 힌트를 사용하여 제품 이미지를 로드하거나 덜 일반적인 사용자 상호작용에만 필요한 추가 JS/CSS를 사용할 수 있습니다.

현재 제한사항

Chrome에서 구현된 사전 힌트의 제한사항은 다음과 같습니다.

  • 탐색 요청 (즉, 최상위 문서의 기본 리소스)에만 사용할 수 있습니다.
  • preconnectpreload만 지원합니다 (즉, prefetch는 지원되지 않음).
  • Early Hint 다음에 최종 응답에서 교차 출처 리디렉션이 발생하면 Chrome은 Early Hints를 통해 얻은 리소스와 연결을 삭제합니다.

다른 브라우저에도 유사한 제한사항이 있으며 103개의 초기 힌트가 preconnect로만 추가로 제한됩니다.

다음 단계

커뮤니티의 관심에 따라 다음 기능을 사용해 사전 힌트 구현을 보강할 수 있습니다.

  • 하위 리소스 요청에서 전송된 조기 힌트입니다.
  • iframe 기본 리소스 요청 시 조기 힌트가 전송됩니다.
  • Early Hints에서 미리 가져오기가 지원됩니다.

우선순위를 두어야 할 측면과 사전 힌트를 더욱 개선하는 방법에 대한 의견을 보내주시기 바랍니다.

H2/푸시와의 관계

지원 중단된 HTTP2/푸시 기능에 익숙하다면 사전 힌트가 어떻게 다른지 궁금하실 텐데요. Early Hints에서는 브라우저가 중요한 하위 리소스를 가져오기 시작하려면 왕복이 필요하지만, HTTP2/Push를 사용하면 서버가 응답과 함께 하위 리소스를 푸시하기 시작할 수 있습니다. 이 기능이 멋지게 들리지만, 이로 인해 핵심적인 구조적 단점이 발생했습니다. HTTP2/Push를 사용하면 브라우저에 이미 있는 하위 리소스를 푸시하기가 매우 어려웠습니다. 이러한 '오버푸시' 효과로 인해 네트워크 대역폭의 사용 효율이 떨어졌으며, 이로 인해 성능상의 이점이 크게 저해되었습니다. 전반적으로 Chrome 데이터에 따르면 HTTP2/Push는 웹 전체의 성능에 순수하지만 부정적인 영향을 미칩니다.

반면 Early Hints는 예비 응답을 보내는 기능과 실제로 필요한 항목을 가져오거나 연결하는 것은 브라우저가 담당하도록 하는 힌트를 결합하기 때문에 성능이 더 좋습니다. Early Hints가 HTTP2/Push가 이론적으로 해결할 수 있는 모든 사용 사례를 다루지는 않지만, Early Hints가 탐색 속도를 높이는 데 보다 실용적인 솔루션이라고 생각합니다.

Pierre Bamin의 썸네일 이미지