서버가 어떻게 중요한 하위 리소스에 대한 힌트를 브라우저에 보낼 수 있는지 알아보세요.
조기 힌트란 무엇인가요?
웹사이트는 점점 더 정교해지고 있습니다. 따라서 서버가 요청된 페이지의 HTML을 생성하기 위해 중요한 작업 (예: 데이터베이스 액세스 또는 원본 서버에 액세스하는 CDN 액세스)을 수행해야 하는 것은 드문 일이 아닙니다. 불행히도, 이러한 '서버 분석 시간'은 브라우저가 페이지 렌더링을 시작하기 전에 추가 지연 시간이 발생합니다. 실제로, 서버가 응답을 준비하는 동안 연결이 사실상 유휴 상태가 됩니다.
<ph type="x-smartling-placeholder">조기 힌트는 최종 응답에 앞서 예비 HTTP 응답을 전송하는 데 사용되는 HTTP 상태 코드 (103 Early Hints
)입니다. 이렇게 하면 서버가 주요 리소스를 생성하느라 바쁜 동안 서버에서 중요한 하위 리소스 (예: 페이지의 스타일 시트, 중요한 JavaScript) 또는 페이지에서 사용할 출처에 대한 힌트를 브라우저에 보낼 수 있습니다. 브라우저는 기본 리소스를 기다리는 동안 이러한 힌트를 사용하여 연결을 준비하고 하위 리소스를 요청할 수 있습니다. 다시 말해, 조기 힌트는 브라우저가 이러한 '서버 생각 시간'을 활용하는 데 도움을 줍니다. 미리 작업을 실행하여 페이지 로드 속도를 높입니다.
경우에 따라 Shopify 및 Cloudflare에서 확인한 바에 따르면 최대 콘텐츠 페인트의 성능이 수백 밀리초에서 최대 1초 단축될 수 있습니다(비교 전후의 그림과 같이).
<ph type="x-smartling-placeholder">조기 힌트 사용 방법
조기 힌트를 활용하기 위한 첫 번째 단계는 인기 방문 페이지, 즉 사용자가 웹사이트를 방문할 때 일반적으로 시작하는 페이지를 파악하는 것입니다. 이 URL은 홈페이지일 수도 있고, 다른 웹사이트에서 많은 사용자가 방문하는 경우 인기 제품 목록 페이지일 수도 있습니다. 이러한 진입점이 다른 페이지보다 중요한 이유는 사용자가 웹사이트를 탐색할 때 조기 힌트의 유용성이 감소하기 때문입니다. 즉, 브라우저가 두 번째 또는 세 번째 후속 탐색 시 필요한 모든 하위 리소스를 확보할 가능성이 높기 때문입니다. 좋은 첫인상을 주는 것도 좋은 방법입니다.
우선순위가 지정된 이 방문 페이지 목록이 있으므로 다음 단계는 preconnect
또는 preload
힌트에 적합한 출처 또는 하위 리소스를 식별하는 것입니다. 일반적으로 최대 콘텐츠 페인트 또는 콘텐츠가 포함된 첫 페인트와 같은 주요 사용자 측정항목에 가장 많이 기여하는 출처 및 하위 리소스입니다. 보다 구체적으로, 동기 JavaScript, 스타일시트 또는 웹 글꼴과 같은 렌더링 차단 하위 리소스를 찾아보세요. 마찬가지로 주요 사용자 측정항목에 많이 기여하는 하위 리소스를 호스팅하는 출처를 찾습니다.
또한 기본 리소스에서 이미 preconnect
또는 preload
를 사용 중인 경우 이러한 출처 또는 리소스를 조기 힌트 후보로 고려할 수 있습니다. 자세한 내용은 LCP 최적화 방법을 참고하세요. 그러나 preconnect
및 preload
지시어를 HTML에서 조기 힌트로 단순하게 복사하는 것은 최적의 방법이 아닐 수 있습니다.
이러한 속성을 HTML에서 사용할 때는 일반적으로 Preload Scanner가 HTML에서 발견하지 못하는 리소스(예: 늦게 발견되는 글꼴 또는 배경 이미지)를 preconnect
또는 preload
하는 것이 좋습니다. 조기 힌트에는 HTML이 없으므로 HTML 초기에 발견될 가능성이 있는 중요한 도메인이나 preload
중요 리소스(예: main.css
또는 app.js
미리 로드)에 대신 preconnect
하는 것이 좋습니다. 또한 일부 브라우저에서는 조기 힌트에 대해 preload
를 지원하지 않습니다. 브라우저 지원을 참고하세요.
두 번째 단계는 더 이상 사용되지 않거나 기본 리소스에서 더 이상 사용하지 않을 수 있는 리소스 또는 출처에 조기 힌트를 사용할 위험을 최소화하는 것입니다. 예를 들어 자주 업데이트되고 버전이 관리되는 리소스 (예: example.com/css/main.fa231e9c.css
)는 최선의 선택이 아닐 수 있습니다. 이 문제는 초기 힌트에만 국한되지 않으며 preload
또는 preconnect
가 있을 수 있는 모든 경우에 적용됩니다. 이러한 세부정보는 자동화 또는 템플릿에 가장 적합합니다. 예를 들어 수동 프로세스를 사용하면 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">
마지막으로 서버 측에서 Early Hints를 지원하는 것으로 알려진 브라우저에서 보낸 주요 리소스 요청을 찾아 즉시 103 Early Hints로 응답합니다. 103 응답에서 관련 사전 연결 및 미리 로드 힌트를 포함합니다. 기본 리소스가 준비되면 일반적인 응답 (예: 성공한 경우 200 OK)으로 후속 조치를 취합니다. 이전 버전과의 호환성을 위해 최종 응답에 Link
HTTP 헤더도 포함하는 것이 좋습니다. 아마도 기본 리소스 생성의 일부로 확인된 중요한 리소스로 보강하는 것이 좋습니다 (예: 'split in two' 제안을 따랐다면 키 리소스의 동적 부분). 다음과 같이 표시됩니다.
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 조기 힌트는 모든 주요 브라우저에서 지원되지만, 조기 힌트에서 전송할 수 있는 지시어는 브라우저에 따라 다릅니다.
사전 연결 지원:
브라우저 지원
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
미리 로드 지원:
브라우저 지원
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
또한 Chrome DevTools에는 103 조기 힌트 지원이 있으며 Link
헤더는 문서 리소스에서 볼 수 있습니다.
조기 힌트는 브라우저 캐시를 사용하므로 DevTools에서 Disable cache
를 선택하지 않아야 합니다. 미리 로드된 리소스의 경우 initiator는 early-hints
으로, size는 (Disk cache)
로 표시됩니다.
또한 HTTPS 테스트를 위한 신뢰할 수 있는 인증서가 필요합니다.
Firefox (v126 현재)는 DevTools에서 명시적인 103 조기 힌트 지원을 제공하지 않지만 조기 힌트를 사용하여 로드된 리소스는 초기 힌트를 통해 로드되었음을 나타내는 지표인 HTTP 헤더 정보를 표시하지 않습니다.
서버 지원
다음은 널리 사용되는 오픈소스 소프트웨어 HTTP 서버 소프트웨어의 Early Hints 지원 수준에 대한 간략한 요약입니다.
더 쉬운 방법으로 조기 힌트 사용 설정
다음 CDN 또는 플랫폼 중 하나를 사용 중인 경우 조기 힌트를 수동으로 구현하지 않아도 됩니다. 솔루션 제공업체의 온라인 문서에서 조기 힌트를 지원하는지 확인하거나 아래의 일부 목록을 참고하세요.
조기 힌트를 지원하지 않는 클라이언트의 문제를 방지하는 방법
100개 범위의 정보 HTTP 응답은 HTTP 표준의 일부이지만 103개의 Early Hints가 출시되기 전에는 일반적인 웹 탐색에 거의 사용되지 않았기 때문에 일부 오래된 클라이언트나 봇에서 이 응답에서 어려움을 겪을 수 있습니다.
sec-fetch-mode: navigate
HTTP 요청 헤더를 전송하는 클라이언트에 대한 응답으로 103개의 조기 힌트만 내보내면 후속 응답을 기다리는 것을 이해하는 신규 클라이언트에만 이러한 힌트가 전송되도록 해야 합니다. 또한 조기 힌트는 탐색 요청에서만 지원 (현재 제한사항 참고)하므로 다른 요청에서 불필요하게 이러한 힌트를 전송하지 않아도 된다는 추가적인 이점이 있습니다.
또한 조기 힌트는 HTTP/2 또는 HTTP/3 연결을 통해서만 전송하는 것이 좋으며 대부분의 브라우저는 해당 프로토콜을 통해서만 이를 허용합니다.
고급 패턴
주요 방문 페이지에 조기 힌트를 완전히 적용했고 더 많은 기회를 모색하고 있다면 다음과 같은 고급 패턴에 관심이 있을 수 있습니다.
일반적인 사용자 경험의 일환으로 n번째 페이지 요청을 하는 방문자의 경우, 페이지에서 더 낮은 수준부터 깊이 있는 콘텐츠에 맞춰 조기 힌트 응답을 조정할 수 있습니다. 즉, 우선순위가 낮은 리소스에 조기 힌트를 사용하는 것이 좋습니다. 렌더링을 차단하는 우선순위가 높은 하위 리소스 또는 출처에 집중하는 것이 좋다는 점을 고려하면 이는 직관적이지 않을 수 있습니다. 그러나 방문자가 한동안 탐색하면 브라우저에 이미 중요한 리소스가 모두 있을 가능성이 매우 높습니다. 그 이후에는 우선순위가 더 낮은 리소스로 초점을 전환하는 것이 타당할 수 있습니다. 예를 들어 조기 힌트를 사용하여 제품 이미지를 로드하거나 덜 일반적인 사용자 상호작용에만 필요한 추가 JS/CSS를 사용할 수 있습니다.
현재 제한사항
Chrome에 구현된 조기 힌트의 제한사항은 다음과 같습니다.
- 탐색 요청 (즉, 최상위 문서의 기본 리소스)에만 사용할 수 있습니다.
preconnect
및preload
만 지원합니다 (즉,prefetch
는 지원되지 않음).- 조기 힌트 다음에 최종 응답에서 교차 출처 리디렉션이 발생하면 Chrome에서 조기 힌트를 통해 획득한 리소스와 연결을 중단합니다.
- 조기 힌트를 사용하여 미리 로드된 리소스는 HTTP 캐시에 저장되며 나중에 페이지에서 가져옵니다. 따라서 캐시 가능한 리소스만 조기 힌트를 사용하여 미리 로드할 수 있습니다. 그러지 않으면 리소스를 이중으로 가져옵니다 (한 번은 조기 힌트에서, 또 한 번은 문서에서). Chrome에서는 신뢰할 수 없는 HTTPS 인증서에 대해 HTTP 캐시가 사용 중지됩니다 (페이지 로드를 진행하더라도 사용 중지됨).
- 반응형 이미지 미리 로드 (
imagesrcset
,imagesizes
또는media
사용)는 문서를 만들 때까지 표시 영역이 정의되지 않으므로 HTTP<link>
헤더를 사용할 수 없습니다. 즉, 반응형 이미지를 미리 로드하는 데 103개의 조기 힌트를 사용할 수 없으며 이 힌트를 사용하면 잘못된 이미지가 로드될 수 있습니다. 문제를 더 잘 처리하는 방법에 관한 제안에 관한 토론을 따르세요.
다른 브라우저에도 유사한 제한사항이 있으며 앞서 언급했듯이 일부에서는 초기 힌트 103개를 preconnect
로만 제한합니다.
다음 단계
커뮤니티의 관심에 따라 다음 기능을 통해 조기 힌트 구현을 보강할 수 있습니다.
- HTTP 캐시가 아닌 메모리 캐시를 사용하여 캐시할 수 없는 리소스에 대한 조기 힌트
- 하위 리소스 요청에 대해 전송된 조기 힌트
- iframe 기본 리소스 요청 시 전송된 조기 힌트
- 초기 힌트에서 미리 가져오기를 지원합니다.
우선순위를 두어야 할 부분과 조기 힌트 개선 방법에 대한 의견을 보내주시기 바랍니다.
H2/Push와의 관계
지원 중단된 HTTP2/푸시 기능에 익숙하다면 조기 힌트가 어떻게 다른지 궁금하실 것입니다. Early Hints는 브라우저가 중요한 하위 리소스를 가져오려면 왕복이 필요하지만, HTTP2/Push를 사용하면 서버가 응답과 함께 하위 리소스를 푸시하기 시작할 수 있습니다. 놀랍게 들리지만, 이로 인해 주요 구조적 단점이 발생했습니다. HTTP2/Push의 경우 브라우저에 이미 있는 하위 리소스를 푸시하는 것을 방지하기가 매우 어려웠습니다. 이러한 '과도한 푸시'는 네트워크 대역폭의 사용 효율성이 떨어지고 성능상의 이점을 크게 저해했습니다. 전반적으로 Chrome 데이터에 따르면 HTTP2/Push는 웹 전체의 성능에 있어 순수한 부정적인 영향을 나타냈습니다.
반면에 조기 힌트는 예비 응답 전송 기능과 힌트를 함께 전송하여 브라우저가 실제로 필요한 것을 가져오거나 연결하는 작업을 처리하므로 실제 성능이 더 좋습니다. 조기 힌트가 이론상 HTTP2/Push에서 해결할 수 있는 사용 사례를 모두 다루지는 않지만 탐색 속도를 높이는 데 있어 조기 힌트가 더 실용적인 솔루션이라고 생각합니다.
썸네일 이미지: 피에르 바민