fetchpriority (페치프라이오리티)로 리소스 로딩 최적화하기

fetchpriority (페치프라이오리티)로 리소스 로딩 최적화하기

배경

미리 로딩(Preloading)은 전체 웹페이지 로딩이 완료되기 전에 주요 콘텐츠를 먼저 로드하여 사용자에게 더 나은 경험을 제공하고 대기 시간을 줄일 수 있게 해줍니다.

하지만 어떤 경우에는 미리 로드된 리소스의 우선순위를 더욱 세분화해야 할 필요도 있습니다.

미리 로딩만으로는 리소스 우선순위를 완벽하게 제어할 수 없기 때문에, 이를 보완하기 위해 fetchpriority (페치프라이오리티) 속성이 도입되었습니다.

목표

리소스 가져오기 우선순위에 영향을 줍니다.


미리 로드된 리소스의 로딩 순서를 보완합니다.


우선순위는 브라우저에게 리소스의 상대적인 중요도를 나타냅니다.

적절한 우선순위 설정은 최적의 로딩을 보장하여 웹 사용자 경험을 향상시킵니다.

리소스 우선순위

브라우저가 웹페이지를 파싱하고 이미지, JavaScript (자바스크립트), CSS (씨에스에스) 및 기타 리소스를 다운로드하기 시작하면 각 리소스에 다운로드 우선순위를 나타내는 fetchpriority (페치프라이오리티) 플래그(여기서는 일반적인 우선순위 개념을 의미)를 할당합니다.

리소스가 다운로드되는 순서는 여러 요인에 의해 결정되는 이 우선순위 플래그에 따라 달라집니다.

CSS (씨에스에스), 글꼴, 스크립트, 이미지 및 타사 리소스에는 서로 다른 우선순위가 할당됩니다.


문서 내 리소스의 위치나 순서가 우선순위에 영향을 미칩니다.



미리 로딩 리소스 힌트는 브라우저가 리소스를 더 빨리 발견하도록 도와 문서 파싱이 완료되기 전에 로드할 수 있게 하여 우선순위에 영향을 줍니다.


스크립트의 async (어씽크) 또는 defer (디퍼) 속성은 우선순위 계산에 영향을 미칩니다.


브라우저는 발견된 순서대로 리소스를 다운로드합니다.

할당된 우선순위는 개발자 도구(DevTools) 네트워크 탭에서 확인할 수 있습니다.

[이미지 설명: 브라우저 개발자 도구의 네트워크 탭 스크린샷. 각 리소스의 이름, 상태, 유형, 크기, 시간 및 우선순위(Priority) 열이 표시되어 있습니다. 일부 리소스는 "Highest", "High", "Medium", "Low" 등의 우선순위를 가지고 있습니다.]

그러나 리소스에 할당된 기본 우선순위가 모든 시나리오에서 항상 최적인 것은 아닙니다.

우선순위 힌트는 언제 사용해야 할까요?

기술적 사용 사례:

우선순위 요구 사항이 다른 여러 화면 상단(above-the-fold) 이미지: 이미지 캐러셀에서는 처음 보이는 이미지만 가장 높은 우선순위를 가져야 합니다.


초기에 낮은 우선순위로 표시된 뷰포트 내 이미지: Chrome (크롬)이 레이아웃 완료 후 해당 이미지가 보이는 것을 감지하면 자동으로 우선순위를 높이지만, 이로 인해 로딩이 지연될 수 있습니다.

우선순위 힌트를 사용하면 더 높은 우선순위로 더 일찍 로드할 수 있습니다.


async (어씽크) 또는 defer (디퍼)로 표시된 스크립트: 이러한 스크립트에는 "낮음(low)" 우선순위가 할당됩니다.

그러나 사용자 경험에 중요한 특정 스크립트는 비동기 로딩을 유지하면서 우선순위를 높여야 할 수 있습니다.


CSS (씨에스에스) 및 글꼴: 브라우저는 기본적으로 CSS (씨에스에스)와 글꼴에 높은 우선순위를 할당하지만 모든 것이 똑같이 중요한 것은 아닙니다.

우선순위 힌트는 덜 중요한 리소스의 우선순위를 낮추는 데 도움이 될 수 있습니다.


fetch() (페치)를 사용한 리소스 가져오기: 브라우저는 기본적으로 fetch() (페치) 요청에 높은 우선순위를 할당합니다.

경우에 따라 모든 요청이 높은 우선순위를 가질 필요는 없습니다.

백그라운드 API (에이피아이) 호출은 낮은 우선순위로 표시하고, 대화형 API (에이피아이) 호출은 높은 우선순위로 표시할 수 있습니다.


제한된 네트워크 대역폭 환경: 사용 가능한 대역폭을 두고 리소스가 경쟁할 때 우선순위 지정의 이점이 특히 중요해집니다.

fetchpriority (페치프라이오리티) 속성

fetchpriority (페치프라이오리티) 속성은 세 가지 값을 허용합니다.

high (하이): 리소스가 중요하다고 간주되어 브라우저에서 우선적으로 처리되어야 합니다.


low (로우): 리소스가 덜 중요하며 우선순위가 낮아야 합니다.


auto (오토): 브라우저가 기본 논리에 따라 우선순위를 결정합니다.

사용 예시:

<!-- 이 화면 상단 이미지는 중요하지 않으므로 우선순위를 낮춥니다. -->
<img
  src="/images/in_viewport_but_not_important.svg"
  fetchpriority="low"
  alt="나는 중요하지 않은 이미지야!"
/>

<!-- 리소스를 일찍 가져오고 싶지만 우선순위를 낮춥니다. -->
<link rel="preload" href="/js/script.js" as="script" fetchpriority="low" />

<script>
  // 낮은 우선순위로 fetch를 실행합니다.
  fetch('https://example.com/', { priority: 'low' }).then((data) => {
    // 데이터를 처리합니다.
  });
</script>

<!-- 이 iframe의 타사 콘텐츠는 낮은 우선순위로 로드될 수 있습니다. -->
<iframe src="https://example.com" width="600" height="400" fetchpriority="low"></iframe>



LCP (최대 콘텐츠풀 페인트) 이미지 우선순위 높이기

예를 들어, Google Flights (구글 플라이츠) 웹페이지에서 낮은 LCP (최대 콘텐츠풀 페인트) 점수의 주요 원인 중 하나는 배경 이미지의 느린 로딩입니다.

fetchpriority (페치프라이오리티) 속성을 사용하여 로딩 우선순위를 높일 수 있습니다.

<img src="lcp-image.jpg" fetchpriority="high" />

우선순위를 high (하이)로 설정하면 LCP (최대 콘텐츠풀 페인트)가 2.6초에서 1.9초로 개선됩니다.

화면 상단(Above-the-Fold) 이미지의 우선순위 낮추기

캐러셀에서 보이지 않는 이미지와 같이 덜 중요한 화면 상단(above-the-fold) 이미지의 우선순위를 낮추기 위해 fetchpriority (페치프라이오리티) 속성을 사용할 수 있습니다.

<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>



미리 로드된 리소스 우선순위 낮추기

미리 로드된 리소스가 다른 중요한 리소스와 경쟁하는 것을 방지하기 위해 명시적으로 우선순위를 낮출 수 있습니다.

<!-- 중요하지 않은 미리 로드된 스크립트에 대해서만 우선순위를 낮춥니다. -->
<link rel="preload" as="script" href="critical-script.js" />
<link rel="preload" href="/js/script.js" as="script" fetchpriority="low" />

<!-- 다른 리소스를 차단하지 않고 CSS를 미리 로드합니다. -->
<link
  rel="preload"
  as="style"
  href="theme.css"
  fetchpriority="low"
  onload="this.rel='stylesheet'"
/>



스크립트 우선순위 조정

페이지에 다른 리소스를 차단해서는 안 되는 중요한 대화형 스크립트가 포함된 경우, 비동기적으로 로드하면서도 높은 우선순위로 표시할 수 있습니다.


(역자 주: importance 속성은 fetchpriority로 변경되었으므로 아래 예제는 fetchpriority를 사용하는 것으로 수정하는 것이 좋습니다.)

<script src="async_but_important.js" async fetchpriority="high"></script>

스크립트가 특정 DOM (돔) 요소에 의존하는 경우 async (어씽크)로 표시할 수 없습니다.

그러나 화면 상단(above-the-fold) 렌더링에 필수적이지 않은 경우 우선순위를 낮출 수 있습니다.

<script src="blocking_but_unimportant.js" fetchpriority="low"></script>

Fetch (페치) 우선순위 조정

기본적으로 브라우저는 높은 우선순위로 fetch() (페치) 요청을 실행합니다.

중요하지 않은 데이터 요청의 우선순위를 낮출 수 있습니다.

// 중요한 유효성 검사 데이터 (기본 높은 우선순위)
let authenticate = await fetch('/user');

// 덜 중요한 콘텐츠 데이터 (낮은 우선순위 제안)
let suggestedContent = await fetch('/content/suggested', { priority: 'low' });



고려 사항

우선순위 힌트는 특정 사용 사례에서 성능을 향상시킬 수 있지만 몇 가지 유의해야 할 사항이 있습니다.

fetchpriority (페치프라이오리티) 속성은 지시문이 아닌 힌트입니다.

브라우저는 개발자 기본 설정을 존중하려고 하지만 내부 우선순위 지정 논리에 따라 재정의할 수 있습니다.

우선순위 힌트와 미리 로딩을 혼동하지 마십시오.

서로 다른 목적을 가지고 있습니다.

미리 로딩은 리소스 가져오기를 강제하는 반면, 우선순위 힌트는 제안일 뿐입니다.


미리 로딩은 관찰하고 측정하기가 더 쉽습니다.


우선순위 힌트는 우선순위 수준에 대한 더 세분화된 제어를 제공하여 미리 로딩을 보완합니다.

LCP (최대 콘텐츠풀 페인트) 이미지가 페이지 상단에서 미리 로드되는 경우 높은 우선순위 힌트는 큰 이점을 제공하지 않을 수 있습니다.

그러나 덜 중요한 리소스 이후에 미리 로딩이 발생하는 경우 높은 우선순위 힌트는 LCP (최대 콘텐츠풀 페인트)를 향상시킬 수 있습니다.

중요한 CSS (씨에스에스) 배경 이미지의 경우 fetchpriority="high" (페치프라이오리티 하이)를 사용하십시오.

CDN (씨디엔)에는 HTTP/2 (에이치티티피 투) 우선순위 지정에 대한 통일된 구현이 없습니다.

브라우저가 우선순위 힌트를 전달하더라도 CDN (씨디엔)이 요청된 우선순위 순서를 존중하지 않을 수 있습니다.

추가 참고 사항

importance (임포턴스) 속성

importance (임포턴스) 우선순위 힌트는 2018년 Chrome (크롬)에서 실험적 기능으로 처음 도입되었고, 2021년에 다시 검토되었습니다.

웹 표준 프로세스의 일환으로 이후 대체되었습니다.

HTML (에이치티엠엘)에서는 속성이 fetchpriority (페치프라이오리티)로 이름이 변경되었습니다.


JavaScript (자바스크립트)에서는 priority (프라이오리티) 옵션으로 대체되었습니다.