Fetch Priority API는 브라우저에 대한 리소스의 상대적 우선순위를 나타냅니다. 이를 통해 최적의 로드를 사용 설정하고 Core Web Vitals를 개선할 수 있습니다.
브라우저가 웹페이지를 파싱하고 이미지, 스크립트, CSS와 같은 리소스를 검색하고 다운로드하기 시작하면 최적의 순서로 다운로드할 수 있도록 가져오기 priority
를 할당합니다. 리소스의 우선순위는 일반적으로 리소스의 유형과 문서 내 위치에 따라 달라집니다. 예를 들어 시점 내 이미지의 우선순위는 High
일 수 있고 <head>
에서 <link>
를 사용하여 조기에 로드된 렌더링 차단 CSS의 우선순위는 Very High
일 수 있습니다. 브라우저는 잘 작동하는 우선순위를 할당하는 데 능숙하지만 모든 경우에 최적은 아닐 수 있습니다.
이 페이지에서는 Fetch Priority API와 fetchpriority
HTML 속성을 설명합니다. 이 속성을 사용하면 리소스의 상대적 우선순위 (high
또는 low
)를 암시할 수 있습니다. Fetch Priority는 Core Web Vitals를 최적화하는 데 도움이 될 수 있습니다.
요약
가져오기 우선순위가 도움이 되는 몇 가지 주요 영역:
- 이미지 요소에
fetchpriority="high"
를 지정하여 LCP 이미지의 우선순위를 높이면 LCP가 더 빨리 발생합니다. - 현재 가장 일반적인 해킹 (
async
스크립트에<link rel="preload">
삽입)보다 더 나은 시맨틱을 사용하여async
스크립트의 우선순위를 높입니다. - 이미지와의 시퀀싱을 개선하기 위해 뒷부분 스크립트의 우선순위를 낮춥니다.
이전에는 개발자가 preload 및 preconnect를 사용하여 리소스 우선순위에 미치는 영향이 제한적이었지만 미리 로드를 사용하면 브라우저가 자연스럽게 발견하기 전에 미리 로드하려는 중요한 리소스를 브라우저에 알릴 수 있습니다. 이는 스타일시트에 포함된 글꼴, 배경 이미지 또는 스크립트에서 로드된 리소스와 같이 찾기 어려운 리소스에 특히 유용합니다. 사전 연결은 교차 출처 서버에 대한 연결을 준비하는 데 도움이 되며 Time to First Byte와 같은 측정항목을 개선하는 데 도움이 될 수 있습니다. 출처는 알고 있지만 필요한 리소스의 정확한 URL은 모르는 경우에 유용합니다.
가져오기 우선순위는 이러한 리소스 힌트를 보완합니다. fetchpriority
속성을 통해 사용할 수 있는 마크업 기반 신호로, 개발자가 특정 리소스의 상대적 우선순위를 나타내는 데 사용할 수 있습니다. JavaScript와 Fetch API를 통해 priority
속성과 함께 이러한 힌트를 사용하여 데이터에 대해 실행되는 리소스 가져오기의 우선순위에 영향을 줄 수도 있습니다. 가져오기 우선순위는 미리 로드를 보완할 수도 있습니다. 최대 콘텐츠 렌더링 시간 이미지를 예로 들 수 있습니다. 이 이미지는 미리 로드되더라도 우선순위가 낮습니다. 다른 우선순위가 낮은 초기 리소스에 의해 이미지가 뒤로 밀리는 경우 가져오기 우선순위를 사용하면 이미지가 얼마나 빨리 로드되는지 확인할 수 있습니다.
리소스 우선순위
리소스 다운로드 시퀀스는 브라우저에서 페이지의 모든 리소스에 할당한 우선순위에 따라 다릅니다. 우선순위 계산 로직에 영향을 줄 수 있는 요소는 다음과 같습니다.
- CSS, 글꼴, 스크립트, 이미지, 서드 파티 리소스와 같은 리소스 유형입니다.
- 문서에서 리소스를 참조하는 위치 또는 순서입니다.
- 스크립트에
async
또는defer
속성이 사용되는지 여부입니다.
다음 표는 Chrome에서 대부분의 리소스에 우선순위를 지정하고 순서를 지정하는 방법을 보여줍니다.
레이아웃 차단 단계에서 로드 | 레이아웃 차단 단계에서 한 번에 하나씩 로드 | ||||
---|---|---|---|---|---|
Blink 우선순위 |
VeryHigh | 높음 | 중간 | 낮음 | VeryLow |
DevTools 우선순위 |
가장 높음 | 높음 | 중간 | 낮음 | 최저 |
기본 리소스 | |||||
CSS (초기**) | CSS (늦음**) | CSS (미디어 불일치***) | |||
스크립트 (조기** 또는 미리 로드 스캐너에서 가져온 것인지 여부) | 스크립트 (늦음**) | 스크립트 (비동기) | |||
글꼴 | 글꼴 (rel=preload) | ||||
가져오기 | |||||
이미지 (뷰포트 내) | 이미지 (첫 5개 이미지: 10,000px2 초과) | 이미지 | |||
미디어 (동영상/오디오) | |||||
프리페치 | |||||
XSL | |||||
XHR (동기화) | XHR/fetch* (비동기) |
브라우저는 계산된 우선순위가 동일한 리소스를 발견된 순서대로 다운로드합니다. Chrome DevTools 네트워크 탭에서 페이지를 로드할 때 다양한 리소스에 할당된 우선순위를 확인할 수 있습니다. 테이블 헤더를 오른쪽 클릭하고 priority 열을 선택하여 포함해야 합니다.
우선순위가 변경되면 대규모 요청 행 설정 또는 도움말에서 초기 우선순위와 최종 우선순위를 모두 확인할 수 있습니다.
가져오기 우선순위가 필요한 경우는 언제인가요?
이제 브라우저의 우선순위 지정 로직을 이해했으므로 페이지의 다운로드 순서를 조정하여 성능과 Core Web Vitals를 최적화할 수 있습니다. 다음은 리소스 다운로드의 우선순위에 영향을 미치도록 변경할 수 있는 몇 가지 예입니다.
<script>
및<link>
와 같은 리소스 태그를 브라우저에서 다운로드할 순서대로 배치합니다. 우선순위가 동일한 리소스는 일반적으로 발견된 순서대로 로드됩니다.preload
리소스 힌트를 사용하여 필요한 리소스를 더 일찍 다운로드합니다. 특히 브라우저에서 초기에 쉽게 찾을 수 없는 리소스에 유용합니다.async
또는defer
를 사용하여 다른 리소스를 차단하지 않고 스크립트를 다운로드합니다.- 브라우저가 더 중요한 상단 콘텐츠에 사용 가능한 대역폭을 사용할 수 있도록 아래쪽 콘텐츠를 지연 로드합니다.
이러한 기법은 브라우저의 우선순위 계산을 제어하여 성능과 Core Web Vitals를 개선하는 데 도움이 됩니다. 예를 들어 중요한 배경 이미지가 미리 로드되면 훨씬 더 일찍 발견되어 최대 콘텐츠 렌더링 시간 (LCP)이 개선됩니다.
이러한 핸들은 애플리케이션에 가장 적합한 리소스의 우선순위를 지정하기에는 충분하지 않을 수 있습니다. 가져오기 우선순위가 유용할 수 있는 시나리오는 다음과 같습니다.
- 스크롤 없이 볼 수 있는 부분에 표시되는 이미지가 여러 개 있지만 모두 동일한 우선순위를 가질 필요는 없습니다. 예를 들어 이미지 캐러셀에서 처음 표시되는 이미지에만 우선순위가 높아야 하며, 나머지 이미지는 일반적으로 처음에는 화면 밖에 있으므로 우선순위가 낮게 설정될 수 있습니다.
- 뷰포트 내의 이미지는 일반적으로
Low
우선순위로 시작합니다. 레이아웃이 완료되면 Chrome은 이러한 요소가 표시 영역에 있음을 감지하고 우선순위를 높입니다. 이렇게 하면 일반적으로 히어로 이미지와 같은 중요한 이미지를 로드하는 데 상당한 지연이 발생합니다. 마크업에서 가져오기 우선순위를 제공하면 이미지가High
우선순위로 시작되고 훨씬 더 일찍 로드되기 시작합니다. 이를 어느 정도 자동화하기 위해 Chrome에서 처음 5개의 더 큰 이미지를Medium
우선순위로 설정합니다. 이는 도움이 되지만 명시적fetchpriority="high"
가 더 좋습니다.
CSS 배경으로 포함된 LCP 이미지를 조기에 검색하려면 여전히 미리 로드가 필요합니다. 배경 이미지의 우선순위를 높이려면 미리 로드에fetchpriority='high'
를 포함합니다. - 스크립트를
async
또는defer
로 선언하면 브라우저에 스크립트를 비동기식으로 로드하라는 신호가 전달됩니다. 그러나 우선순위 표에 표시된 것처럼 이러한 스크립트에도 '낮음' 우선순위가 할당됩니다. 특히 사용자 환경에 중요한 스크립트의 경우 비동기 다운로드를 보장하면서 우선순위를 높일 수 있습니다. - JavaScript
fetch()
API를 사용하여 리소스 또는 데이터를 비동기식으로 가져오면 브라우저는High
우선순위를 할당합니다. 특히 백그라운드 API 호출을 사용자 입력에 응답하는 API 호출과 혼합하는 경우 일부 가져오기를 더 낮은 우선순위로 실행하는 것이 좋습니다. 백그라운드 API 호출을Low
우선순위로, 대화형 API 호출을High
우선순위로 표시합니다. - 브라우저는 CSS 및 글꼴에
High
우선순위를 할당하지만 이러한 리소스 중 일부는 다른 리소스보다 중요할 수 있습니다. 가져오기 우선순위를 사용하여 중요하지 않은 리소스의 우선순위를 낮출 수 있습니다. 초기 CSS는 렌더링을 차단하므로 일반적으로High
우선순위여야 합니다.
fetchpriority
속성
fetchpriority
HTML 속성을 사용하여 link
, img
또는 script
태그를 사용하여 다운로드할 때 CSS, 글꼴, 스크립트, 이미지와 같은 리소스 유형의 다운로드 우선순위를 지정합니다. 다음 값을 사용할 수 있습니다.
high
: 리소스의 우선순위가 더 높으며 브라우저 자체 휴리스틱이 이를 방해하지 않는 한 브라우저에서 평소보다 더 높은 우선순위를 두도록 합니다.low
: 리소스의 우선순위가 낮으며 브라우저가 휴리스틱이 허용하는 경우 다시 우선순위를 낮추도록 합니다.auto
: 브라우저가 적절한 우선순위를 선택할 수 있는 기본값입니다.
다음은 마크업에서 fetchpriority
속성을 사용하는 예와 스크립트와 동일한 priority
속성의 예입니다.
<!-- We don't want a high priority for this above-the-fold image -->
<img src="/images/in_viewport_but_not_important.svg" fetchpriority="low" alt="I'm an unimportant image!">
<!-- We want to initiate an early fetch for a resource, but also deprioritize it -->
<link rel="preload" href="/js/script.js" as="script" fetchpriority="low">
<script>
fetch('https://example.com/', {priority: 'low'})
.then(data => {
// Trigger a low priority fetch
});
</script>
브라우저 우선순위 및 fetchpriority
의 효과
다음 표와 같이 fetchpriority
속성을 다양한 리소스에 적용하여 계산된 우선순위를 높이거나 낮출 수 있습니다. 각 행의 fetchpriority="auto"
(◉)는 해당 유형의 리소스에 대한 기본 우선순위를 표시합니다. (Google 문서로도 제공됨)
레이아웃 차단 단계에서 로드 | 레이아웃 차단 단계에서 한 번에 하나씩 로드 | ||||
---|---|---|---|---|---|
Blink 우선순위 |
VeryHigh | 높음 | 중간 | 낮음 | VeryLow |
DevTools 우선순위 |
가장 높음 | 높음 | 중간 | 낮음 | 최저 |
기본 리소스 | ◉ | ||||
CSS (초기**) | ⬆◉ | ⬇ | |||
CSS (늦음**) | ⬆ | ◉ | ⬇ | ||
CSS (미디어 불일치***) | ⬆*** | ◉⬇ | |||
스크립트 (조기** 또는 미리 로드 스캐너에서 가져온 것인지 여부) | ⬆◉ | ⬇ | |||
스크립트 (늦음**) | ⬆ | ◉ | ⬇ | ||
스크립트 (async/defer) | ⬆ | ◉⬇ | |||
글꼴 | ◉ | ||||
글꼴 (rel=preload) | ⬆◉ | ⬇ | |||
가져오기 | ◉ | ||||
이미지 (뷰포트 내 - 레이아웃 후) | ⬆◉ | ⬇ | |||
이미지 (첫 5개 이미지: 10,000px2 초과) | ⬆ | ◉ | ⬇ | ||
이미지 | ⬆ | ◉⬇ | |||
미디어 (동영상/오디오) | ◉ | ||||
XHR (동기화) - 지원 중단됨 | ◉ | ||||
XHR/fetch* (비동기) | ⬆◉ | ⬇ | |||
프리페치 | ◉ | ||||
XSL | ◉ |
fetchpriority
는 상대 우선순위를 설정합니다. 즉, 우선순위를 High
또는 Low
로 명시적으로 설정하는 대신 기본 우선순위를 적절한 양만큼 올리거나 내립니다. 이로 인해 High
또는 Low
우선순위가 주어지는 경우가 많지만 항상 그런 것은 아닙니다. 예를 들어 fetchpriority="high"
가 있는 중요 CSS는 '매우 높음'/'가장 높음' 우선순위를 유지하고 이러한 요소에 fetchpriority="low"
를 사용하면 '높음' 우선순위가 유지됩니다. 이 두 경우 모두 우선순위를 High
또는 Low
로 명시적으로 설정하지 않습니다.
사용 사례
브라우저에 리소스를 가져올 우선순위에 관한 추가 힌트를 제공하려면 fetchpriority
속성을 사용하세요.
LCP 이미지의 우선순위 높이기
fetchpriority="high"
를 지정하여 LCP 또는 기타 중요한 이미지의 우선순위를 높일 수 있습니다.
<img src="lcp-image.jpg" fetchpriority="high">
다음 비교에서는 가져오기 우선순위 유무와 관계없이 LCP 배경 이미지가 로드된 Google 항공편 검색 페이지를 보여줍니다. 우선순위를 높음으로 설정하면 LCP가 2.6초에서 1.9초로 개선되었습니다.
스크롤 없이 볼 수 있는 부분에 표시되는 이미지의 우선순위 낮추기
fetchpriority="low"
를 사용하여 이미지 캐러셀의 오프스크린 이미지와 같이 당장 중요하지 않은 상단 이미지의 우선순위를 낮춥니다.
<ul class="carousel">
<img src="img/carousel-1.jpg" fetchpriority="high">
<img src="img/carousel-2.jpg" fetchpriority="low">
<img src="img/carousel-3.jpg" fetchpriority="low">
<img src="img/carousel-4.jpg" fetchpriority="low">
</ul>
이미지 2~4는 뷰포트 외부에 있지만 high
로 확대하고 load=lazy
속성이 추가되더라도 로드할 만큼 '충분히 가깝게' 있는 것으로 간주될 수 있습니다. 따라서 fetchpriority="low"
이 올바른 해결책입니다.
이전에 Oodle 앱을 실험할 때 이 방법을 사용하여 로드 시 표시되지 않는 이미지의 우선순위를 낮췄습니다. 페이지 로드 시간이 2초 단축되었습니다.
미리 로드된 리소스의 우선순위 낮추기
미리 로드된 리소스가 다른 중요한 리소스와 경쟁하지 않도록 하려면 우선순위를 낮추면 됩니다. 이 기법은 이미지, 스크립트, CSS와 함께 사용합니다.
<!-- Lower priority only for non-critical preloaded scripts -->
<link rel="preload" as="script" href="critical-script.js">
<link rel="preload" as="script" href="non-critical-script.js" fetchpriority="low">
<!-- Preload CSS without blocking render, or other resources -->
<link rel="preload" as="style" href="theme.css" fetchpriority="low" onload="this.rel='stylesheet'">
스크립트 우선순위 변경
페이지가 상호작용이 가능하도록 하는 스크립트는 빠르게 로드되어야 하지만 더 중요한 렌더링 차단 리소스를 차단해서는 안 됩니다. 이러한 작업은 우선순위가 높은 async
로 표시할 수 있습니다.
<script src="async_but_important.js" async fetchpriority="high"></script>
특정 DOM 상태를 사용하는 스크립트는 async
로 표시할 수 없습니다. 하지만 페이지에서 나중에 실행되는 경우 우선순위를 낮춰 로드할 수 있습니다.
<script src="blocking_but_unimportant.js" fetchpriority="low"></script>
이렇게 하면 파서가 이 스크립트에 도달할 때 여전히 차단되지만 그 이전의 콘텐츠에는 우선순위가 부여됩니다.
완성된 DOM이 필요한 경우 defer
속성 (DOMContentLoaded 후에 순서대로 실행됨)을 사용하거나 페이지 하단의 async
를 사용하는 것도 방법입니다.
중요하지 않은 데이터 가져오기의 우선순위 낮추기
브라우저는 높은 우선순위로 fetch
를 실행합니다. 동시에 실행될 수 있는 가져오기가 여러 개인 경우 더 중요한 데이터 가져오기에 높은 기본 우선순위를 사용하고 덜 중요한 데이터의 우선순위를 낮출 수 있습니다.
// Important validation data (high by default)
let authenticate = await fetch('/user');
// Less important content data (suggested low)
let suggestedContent = await fetch('/content/suggested', {priority: 'low'});
가져오기 우선순위 구현 메모
가져오기 우선순위를 사용하면 특정 사용 사례에서 성능을 개선할 수 있지만 가져오기 우선순위를 사용할 때는 몇 가지 사항에 유의해야 합니다.
fetchpriority
속성은 지시어가 아닌 힌트입니다. 브라우저는 개발자의 환경설정을 따르려고 하지만 충돌을 해결하기 위해 리소스 우선순위에 대한 리소스 우선순위 환경설정을 적용할 수도 있습니다.가져오기 우선순위를 미리 로드와 혼동하지 마세요.
- 미리 로드는 힌트가 아닌 필수 가져오기입니다.
- 미리 로드하면 브라우저가 리소스를 일찍 발견할 수 있지만 여전히 기본 우선순위로 리소스를 가져옵니다. 반대로 가져오기 우선순위는 검색 가능성에는 도움이 되지 않지만 가져오기 우선순위를 높이거나 낮출 수는 있습니다.
- 우선순위 변경의 효과보다 미리 로드의 효과를 관찰하고 측정하는 것이 더 쉬운 경우가 많습니다.
가져오기 우선순위는 우선순위 지정 세부사항을 늘려 미리 로드를 보완할 수 있습니다. LCP 이미지의
<head>
에서 첫 번째 항목 중 하나로 미리 로드를 이미 지정한 경우high
가져오기 우선순위로 LCP가 크게 개선되지 않을 수 있습니다. 그러나 다른 리소스가 로드된 후에 미리 로드가 발생하는 경우high
가져오기 우선순위로 LCP를 더 개선할 수 있습니다. 중요한 이미지가 CSS 배경 이미지인 경우fetchpriority = "high"
로 미리 로드합니다.우선순위에 따른 로드 시간 개선은 사용 가능한 네트워크 대역폭을 더 많은 리소스가 경쟁하는 환경에서 더 적합합니다. 이는 동시 다운로드가 불가능한 HTTP/1.x 연결이나 대역폭이 낮은 HTTP/2 또는 HTTP/3 연결에서 일반적입니다. 이러한 경우 우선순위를 지정하면 병목 현상을 해결하는 데 도움이 될 수 있습니다.
CDN은 HTTP/2 우선순위 지정을 일관되게 구현하지 않으며 HTTP/3도 마찬가지입니다. 브라우저가 가져오기 우선순위에서 우선순위를 전달하더라도 CDN에서 지정된 순서대로 리소스의 우선순위를 다시 지정하지 않을 수 있습니다. 따라서 가져오기 우선순위를 테스트하기가 어렵습니다. 우선순위는 브라우저 내부에서 그리고 우선순위를 지원하는 프로토콜 (HTTP/2 및 HTTP/3)과 함께 적용됩니다. 브라우저가 리소스를 요청할 때 우선순위가 자주 변경되므로 CDN 또는 출처 지원과 관계없이 내부 브라우저 우선순위에만 가져오기 우선순위를 사용하는 것이 좋습니다. 예를 들어 이미지와 같은 우선순위가 낮은 리소스는 브라우저가 중요한
<head>
항목을 처리하는 동안 요청되지 않는 경우가 많습니다.초기 설계에서 가져오기 우선순위를 권장사항으로 도입하지 못할 수도 있습니다. 개발 주기 후반에 페이지의 여러 리소스에 할당된 우선순위를 확인할 수 있으며, 기대에 미치지 않는 경우 가져오기 우선순위를 도입하여 추가로 최적화할 수 있습니다.
개발자는 의도된 목적(파서에서 감지하지 못한 리소스(서체, 가져오기, 배경 LCP 이미지) 미리 로드)에 맞게 미리 로드를 사용해야 합니다. preload
힌트의 위치는 리소스가 미리 로드되는 시점에 영향을 미칩니다.
가져오기 우선순위는 리소스를 가져올 때 리소스를 가져오는 방법에 관한 것입니다.
미리 로드 사용 관련 도움말
미리 로드를 사용할 때는 다음 사항에 유의하세요.
- HTTP 헤더에 미리 로드를 포함하면 로드 순서에서 다른 모든 항목 앞에 미리 로드가 배치됩니다.
- 일반적으로 미리 로드는
Medium
우선순위 이상인 항목의 경우 파서가 해당 항목에 도달하는 순서대로 로드됩니다. HTML 시작 부분에 미리 로드할 항목을 포함하는 경우 주의하세요. - 글꼴 미리 로드는 헤더 끝이나 본문 시작 부분에서 가장 효과적입니다.
- 가져오기 미리 로드 (동적
import()
또는modulepreload
)는 가져오기가 필요한 스크립트 태그 뒤에 실행되어야 하므로 종속 항목이 로드되는 동안 평가될 수 있도록 스크립트가 먼저 로드되거나 파싱되어야 합니다. - 이미지 미리 로드는 기본적으로
Low
또는Medium
우선순위가 적용됩니다. 비동기 스크립트 및 기타 낮은 우선순위 또는 최저 우선순위 태그를 기준으로 순서를 지정합니다.
기록
가져오기 우선순위는 2018년에 Chrome에서 오리진 트라이얼로 처음 실험되었으며, 2021년에는 importance
속성을 사용하여 다시 실험되었습니다. 당시에는 우선순위 힌트라고 불렀습니다. 이후 웹 표준 프로세스의 일환으로 인터페이스가 HTML의 경우 fetchpriority
로, JavaScript의 Fetch API의 경우 priority
로 변경되었습니다. 혼란을 줄이기 위해 이제 이 API를 가져오기 우선순위라고 합니다.
결론
개발자는 미리 로드 동작의 수정사항과 최근 Core Web Vitals 및 LCP에 대한 관심과 함께 가져오기 우선순위에 관심을 가질 수 있습니다. 이제 원하는 로드 시퀀스를 실행할 수 있는 추가 노브가 있습니다.