[최적화] 리소스 우선순위 적용하기

이지·2024년 2월 20일
0

웹 최적화

목록 보기
4/5
post-thumbnail

라이트하우스 결과에서 다음 사진과 같은 메시지를 확인했습니다.

1️⃣

2️⃣

해당 메시지를 어떻게 해결해야 하는지, 이와 관련된 리소스 우선순위에 대한 개념과 preload, preconnect, prefetch에 대해 알아보고자 합니다.

리소스 우선순위

웹페이지의 로딩 속도를 최적화하기 위해 특정 리소스들의 다운로드 순서를 조절할 수 있습니다. 이를 통해 사용자가 웹페이지를 빠르게 경험할 수 있어 사용자 경험이 개선되고, 필수 리소스는 더 빠르게 로딩되도록 할 수 있습니다.

주로 HTML의 <head> 안에서 <link> 태그를 사용하여 작성합니다.

preload

  • 특정 리소스를 브라우저가 미리 로딩하도록 합니다.
  • 초기에 빠르게 로딩할 필요가 있는 js, css, font 등에 사용할 수 있습니다.

example code

<link rel="preload" href="style.css" as="style">
<link rel="preload" href="script.js" as="script">

preconnect

  • 특정 도메인과 사전에 연결하도록 설정합니다.
  • 특정 서버와의 사전 연결을 통해 지연 시간을 최소화하여 성능을 향상시킬 수 있습니다.

example code

<link rel="preconnect" href="https://api.example.com">

prefetch

  • 브라우저가 사용자가 방문할 가능성이 있는 리소스를 미리 로딩하도록 할 수 있습니다.
  • 다음 페이지의 이미지나 스크립트를 미리 로딩하여 전환 속도를 향상할 수 있습니다.

example code

<link rel="prefetch" href="next-page-image.jpg">

첫번째 문제 해결하기


위의 메시지에서 말하는 필수 원본은 API 통신에서 사용되는 API 서버의 기본 주소입니다.

<link rel="preconnect" href="API 서버의 기본 주소">

두번째 문제 해결하기

위의 이미지는 홈에서 사용되는 배너이미지 중 첫번째 이미지입니다.
이 이미지를 preload하기 위해 여러가지 방법을 시도했습니다.

방법 1 - fetchpriority

<img src="..." fetchpriority="high" />

React에서 fetchpriority를 사용하기 위한 방법으로
https://stackoverflow.com/questions/73455263/fetch-priority-attribute-in-img-tag-react-js
해당 페이지의 코드를 참고하여 global.d.ts 파일을 새로 만들어서 진행하였습니다.

// global.d.ts
import React from "react";
declare module "react" {
  interface ImgHTMLAttributes<T> extends HTMLAttributes<T> {
    fetchpriority?: "high" | "low" | "auto";
  }
}
// Banner.tsx
...
return (
  ...
    {imgArr.map((img, idx) => (
          <picture key={idx}>
            <source
              srcSet={`${imgArrSm[idx]} 609w, ${imgArrMd[idx]} 1280w, ${imgArrLg[idx]} 1920w`}
              type="image/webp"
            />
            <img
              key={idx}
              src={img}
              alt={`배너이미지${idx + 1}`}
              fetchpriority={idx === 0 ? "high" : "low"} // add
              className={swiperCurrentPosition === idx ? "active" : ""}
            />
          </picture>
        ))}
)

맨 처음에 나타나는 배너의 우선순위만 높게 설정하면 될 것 같다고 생각하였고, 이미지를 배열에 담아놓고 map을 통해 이미지를 나타내고 있어서 idx가 0인( = banner1_...) 이미지에만 fetchpriority="high"를 설정하고 나머지에는 "low"를 설정했습니다.

banner1의 우선순위가 높음으로 설정된 것을 볼 수 있습니다.

한번 더 lighthouse를 검사했는데 "콘텐츠가 포함된 최대 페인트 이미지 미리로드" 메시지는 여전히 나타나고 있었습니다.

Tip. 네트워크 탭에서 우선순위 항목 확인하는 방법

  • 상단 헤더에서 마우스 오른쪽 클릭해서 원하는 항목 선택

    참고

방법 2 - preload

  • 첫번째 배너 이미지를 link태그의 preload를 설정해서 높은 로드 우선순위를 부여했습니다.
  <link rel="preload" as="image" href="%PUBLIC_URL%/img/banner1.jpg" />
  <link rel="preload" as="image" href="%PUBLIC_URL%/img/banner1_lg.webp" />
  <link rel="preload" as="image" href="%PUBLIC_URL%/img/banner1_md.webp" />
  <link rel="preload" as="image" href="%PUBLIC_URL%/img/banner1_sm.webp" />

preload를 적용하고 나니 "콘텐츠가 포함된 최대 페인트 이미지 미리로드" 메시지가 사라졌습니다.

적용 전

적용 후

적용 전과 비교했을 때 1초정도 빠르게 배너이미지를 확인할 수 있었습니다.

preload를 사용할 때 몇 초안에 해당 리소스가 사용되지 않으면 콘솔에서 다음과 같은 경고 메시지가 발생했습니다.

배너를 반응형 이미지를 위해 다양한 사이즈의 이미지와 jpg 파일을 제공하고 있는데, 사용자의 화면 너비에 따라 필요한 이미지는 1가지이기 때문에 나머지 이미지들은 사용되지 않아 이런 메시지가 발생한 것입니다. 사실 이런 경우는 어떻게 해결하면 좋을지 적절한 방법은 아직 찾지 못했습니다..🤔


참고
https://idealstring.tistory.com/44
https://web.dev/articles/optimize-lcp?hl=ko

0개의 댓글

관련 채용 정보