라이트하우스 결과에서 다음 사진과 같은 메시지를 확인했습니다.
1️⃣
2️⃣
해당 메시지를 어떻게 해결해야 하는지, 이와 관련된 리소스 우선순위에 대한 개념과 preload, preconnect, prefetch에 대해 알아보고자 합니다.
웹페이지의 로딩 속도를 최적화하기 위해 특정 리소스들의 다운로드 순서를 조절할 수 있습니다. 이를 통해 사용자가 웹페이지를 빠르게 경험할 수 있어 사용자 경험이 개선되고, 필수 리소스는 더 빠르게 로딩되도록 할 수 있습니다.
주로 HTML의 <head>
안에서 <link>
태그를 사용하여 작성합니다.
example code
<link rel="preload" href="style.css" as="style">
<link rel="preload" href="script.js" as="script">
example code
<link rel="preconnect" href="https://api.example.com">
example code
<link rel="prefetch" href="next-page-image.jpg">
위의 메시지에서 말하는 필수 원본은 API 통신에서 사용되는 API 서버의 기본 주소입니다.
<link rel="preconnect" href="API 서버의 기본 주소">
위의 이미지는 홈에서 사용되는 배너이미지 중 첫번째 이미지입니다.
이 이미지를 preload하기 위해 여러가지 방법을 시도했습니다.
<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. 네트워크 탭에서 우선순위 항목 확인하는 방법
- 상단 헤더에서 마우스 오른쪽 클릭해서 원하는 항목 선택
참고
<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