Santos의 개발블로그

모든 네트워크 활동을 제어하기 with 우선순위 본문

기타

모든 네트워크 활동을 제어하기 with 우선순위

Santos 2023. 10. 21. 18:00

* 이 글은 Get All That Network Activity Under Control with Priority Hints 를 번역 및 정리하였습니다.

 

Get All That Network Activity Under Control with Priority Hints

The browser is very good at prioritizing resources requests on its own. But it's not always great. Priority hints makes it easy to provide explicit instructions as to how and in what network activity occurs.

www.macarthur.me


브라우저의 네트워크 탭을 열면 많은 활동을 확인할 수 있습니다. 에셋이 다운로드되고, 정보가 제출되고, 이벤트가 기록되는 등 다양한 활동이 이루어지고 있습니다.

이렇게 많은 일이 벌어지는 상황에서 트래픽의 우선순위를 효과적으로 관리하는 것은 매우 중요합니다.

 

"우선순위 힌트"는 브라우저 리소스가 제한될 때 어떤 요청을 다른 요청보다 우선적으로 처리해야 하는지에 대한 가정을 줄이고, 더 명확한 결정을 내릴 수 있도록 도와줍니다. 사용할 수 있는 적합한 시나리오를 함께 살펴 봅시다.


1.  <img /> 요청 우선 순위

<img src="./cat-1.jpeg" />
<div style="height: 5000px"></div>
<img src="./cat-2.jpeg" />
<div style="height: 5000px"></div>
<img src="./cat-3.jpeg" />

위와 같이 3개의 이미지를 load 한다고 했을 때, 브라우저는 어느정도 순서를 예측합니다. 아래와 같이 말이죠.

다운로드가 시작되었을 때 세 가지 모두 우선순위가 "낮음"이었습니다. 하지만 얼마 지나지 않아 가장 위에 있는 것이 "높음"으로 바뀌었습니다.

어느정도 브라우저가 예상을 하고 알아서 load를 해주지만, 명시적으로 load 되는 순서를 지정해야 하는 경우도 있습니다. 예를 들면 우선순위를 지정할 수 있는 lazy loading과 같은 곳에서요. 

<img src="./cat-1.jpeg" fetchpriority="high"/>
<div style="height: 5000px"></div>
<img src="./cat-2.jpeg" loading="lazy" />
<div style="height: 5000px"></div>
<img src="./cat-3.jpeg" loading="lazy" />

 fetchpriority 속성을 사용하게 되면 브라우저는 적절한 경우에만 이미지를 로드하는 방법과 로드할지 여부를 정확히 파악합니다. 브라우저에게 명확한 지침을 주게 되는 것이죠.


2.  fetch() 요청 우선 순위

대역폭이 부족하고 여러 요청이 동시에 처리되는 경우 브라우저는 자체적으로 우선순위를 결정하게 됩니다. 하지만 목적과 상황에 따라 더 중요한 다른 요청에 우선순위를 조정해야 할 때는 항시 존재합니다. 이를 가능하게 해주는 fetch API 속성 중 priority에 대해 알아보겠습니다. 

fetch("http://localhost:8000/pay", {
  method: "POST",
  body: paymentBody,
});

fetch("http://localhost:8000/log", {
  method: "POST",
  body: loggingBody,
});

기본적으로 Priority는 high로 설정되어 있습니다. 

fetch("http://localhost:8000/pay", {
  method: "POST",
  body: paymentBody,
  // 알려주자
+ priority: "high"
});

fetch("http://localhost:8000/log", {
  method: "POST",
  body: loggingBody,
  // 알려주자
+ priority: "low"
});

이렇게 명시적으로 우선순위를 적어주면, API 호출 시 브라우저는 우선순위 판단 후 호출을 하게 됩니다. 

네트워크 환경이 좋지 않아 통신이 너무 느릴때 사용자가 페이지를 벗어나면, 우선순위가 낮은 호출은 무시되어 버리는 경우가 발생합니다.
이럴때는 fetch API 속성 중 keepalive를 켜주세요. 해당 페이지가 종료되더라도 브라우저는 해당 요청을 중단하지 않고 지속합니다.   


3.  <script /> 태그 우선 순위

페이지에 src 속성이 있는 일반 <script />는 가져올 때 우선순위가 high지만, 페이지가 로드되고 실행될 때까지 나머지 페이지의 구문 분석이 차단된다는 단점이 있습니다. 이러한 이유로 async 속성이 유용합니다. 우선순위 low로 백그라운드에서 스크립트를 요청하고 스크립트가 준비되는 즉시 실행합니다. 이를 알면 다음 설정이 예상대로 작동합니다.

<script src="/script-async.js" async onload="console.log('async')"></script>
<script src="/script-sync.js" onload="console.log('sync')"></script>
<script>console.log("inline");</script>

그리고 콘솔은 async 스크립트가 로드되는 동안 후속 스크립트가 구문 분석 및 실행되도록 허용되었는지 확인합니다.

스크립트를 비동기적으로 "높은" 우선순위로 로드하고 싶은 경우 🙏

<script src="/script-async.js" async onload="console.log('async')" fetchpriority="high"></script>
<script src="/script-sync.js" onload="console.log('sync')"></script>
<script>console.log("inline");</script>

fetchpriority 속성에 high를 넣어주면, 나머지 페이지를 차단하지 않으면서도 높은 우선순위로 다운로드됩니다.


4.  preload 된 asset 의 우선 순위

<head>에 배치된 브라우저의 프리로드 스캐너 <link rel="preload" ... /> 는 이미 이런 작업에 매우 능숙합니다. 브라우저는 "높음" 우선순위로 빨리 다운로드를 시작하게 됩니다. 

따라서 preloadsms 늦게 발견된 asset, 즉 HTML에서 직접 로드되지 않은 asset에 사용하는 것이 가장 좋습니다. 예를 들어 일부 CSS 내에 load된 글꼴 파일이나 인라인 style 속성을 통해 load된 배경 이미지가 적절한 대상입니다.

기본적으로 Chrome은 매우 높은 우선순위로 글꼴을 load 합니다. 하지만 네트워크 연결 속도가 느린 경우 대체 글꼴을 사용하고 load 우선순위를 낮춥니다. 

글꼴을 load 할때를 예로 들어보겠습니다.

@font-face {
  font-family: "Inter Variable";
  src: url("./font.woff2") format("woff2");
}

네트워크 환경이 좋지 않아 글꼴 load의 우선순위를 현저하게 낮춘 것을 확인 할 수 있습니다. 

<head>
  <!-- 기타 항목... -->
  <link rel="preload" href="/font.woff2" as="font">
</head>

해당 resource를 명시적으로 preload 해보겠습니다. 

우선순위가 굉장히 높아졌죠. 더 명시적으로 표기하려면 link 태그에 직접 fetchpriority를 사용할 수도 있습니다. 이를 통해 한 번에 여러 에셋을 프리로드할 때 상대적인 우선순위를 지정할 수 있습니다.

<link rel="preload" href="./font-1.woff2" as="font" fetchpriority="low" />
<link rel="preload" href="./font-2.woff2" as="font" fetchpriority="high" />

페이지 경험에 중요한 에셋(글꼴, CSS 배경 이미지 등)인 경우 프리로딩을 사용합니다.
또한 같은 유형의 리소스를 여러 개 프리로드할 때 fetchpriority 속성을 포함하면 어떤 리소스가 가장 중요한지 명확하게 알 수 있습니다.

< 참고자료 >

 

[사이트] Get All That Network Activity Under Control with Priority Hints

 

Get All That Network Activity Under Control with Priority Hints

The browser is very good at prioritizing resources requests on its own. But it's not always great. Priority hints makes it easy to provide explicit instructions as to how and in what network activity occurs.

www.macarthur.me

Get All That Network Activity Under Control with Priority Hints end

'기타' 카테고리의 다른 글

Chrome의 내부 동작 #2  (0) 2023.12.14
Chrome의 내부 동작 #1  (0) 2023.12.02
SPA vs SSG vs SSR  (0) 2023.05.21
Polyfill  (0) 2020.01.21
OWASP  (0) 2020.01.18
Comments