Dev/리팩토링

FP->LCP 시간을 줄여보자

rryu09 2024. 9. 13. 12:28

서론

ux를 위해 빈 화면이 뜨는 시간이 적고 빠른 피드백이 필요하다에는 이견이 적을 것이다.

실제로 내 웹이 어떻게 전달되는지 개발자도구를 통해서 살펴봤는데, 개선점이 많아 보강도 할 겸 정리해본다.

 

본론

현재 내 홈페이지를 개발자도구 performance 탭으로 찍어봤다.

LCP가 2.85s로 조금 느린 것을 확인할 수 있다.

FP는 208.8ms로 0.2088초니까...

FP -> LCP 가 2.6412s 가 걸린다!

 

2.5초 내로 LCP가 마무리되는 것이 적절하다고 한다.

 

https://pagespeed.web.dev/analysis/https-www-rryu09-com/u7utvt3zu5?hl=ko&form_factor=desktop

 

PageSpeed Insights

올바른 URL을 입력하세요.

pagespeed.web.dev

검사를 돌려 보면 LCP가 3.4초나 걸린다고 나온다.

 

그런데 코드에서 이상한 부분을 발견했다. Title 밑의 내용들이 전부 Suspense로 감싸져 있던 것.

로딩 장면을 살펴보면 lazy 컴포넌트 밑 부분이 먼저 보였다가 Suspense에 의해서 로더로 교체되고, 3d 캐릭터가 있는 컴포넌트인 RyuDevChar의 로드가 완료되면 그 밑 부분이 한번에 뜨는 것으로 보인다.

Suspense로 왜 전체를 감싼 걸까? 내용이 한번에 보이도록 유도한 것 같지만, 사용성에는 좋지 않아 보인다.

 

Suspense를 아예 없애봤다.

 

다시 살펴봤을 때 LCP가 1.5s, FP 는 395.9ms로, FP->LCP에 눈에 띄는 차이가 생겼다.

3d는 소스셋이 잡히지 않기 때문에 LCP 로 잡히지 않는 것으로 보이고,

이미 렌더링이 완료된 프로젝트 섹션란을 3d가 완료되는 시점에 같이 뜨도록 해 두었으니 3d paint가 완료되는 시점에서 이 정보들이 떠 LCP 가 3초대로 형성되었던 것 같다.

 

여기서 알 수 있는 것:

Suspense 남발은 오히려 성능을 저해할 수 있다. 꼭 필요한 경우에만 쓸 것

 

현재 LCP 요소는 뭘까??

프로젝트 소개란 이미지의 로딩 시간이 오래 걸리는 것 같다.

보고서를 보면 더 자세하게 파악할 수 있다. 렌더링 지연이 88%로 가장 큰 비율을 차지하고 있는데, 이건 어느 단계에서 어떻게 이루어지고 어떻게 절감할 수 있는걸까?

 

Element render delay(요소 렌더 지연): LCP 리소스가 로딩을 끝내고 LCP 요소가 완전히 렌더링 되는때까지의 사이의 값

 

그렇다면 LCP 요소에 우선순위를 부여해서 빠르게 렌더링을 시작하면 되지 않을까?

 

Image 태그에 이미 priority 속성이 붙어 있었다. 이걸 제거하면 훨씬 느려지게 되는 걸까? (사실 next의 Image 컴포넌트는 이미 최적화에 상당히 공을 들였다. 크기별 소스를 생성해주기도 하고, 네트워크 탭을 확인해보면 속도가 빠른 webp 형식으로 받아오는 것을 볼 수 있다.) 

 

네트워크 환경에 따라 차이가 있을 수 있으므로 3회 측정함

 

with priority

1차: LCP 1.18s, FP 134.99ms ~= 1.045

2차: LCP 1.21s, FP 164.08ms ~= 1.046

3차: LCP 1.35s, FP 142.13ms ~= 1.208

평균: 약 1.11s

 

w/o priority

1차: LCP 1.70s, FP 440.7ms ~= 1.26

2차: LCP 1.26s, FP 136.65ms ~= 1.123

3차: LCP 1.39s, FP 138.18ms ~= 1.252

평균: 약 1.21s

 

대략 0.1초 정도의 차이가 있었다.

LCP 가 2초정도 된다고 했을 때 0.1초 줄여도 1.9초니까 딱히 유의미하지는 않아보인다.

로드되어야 하는 양이 많지 않아 워터폴의 마지막에 로드를 시작하나 시작부분에 하나 별 차이가 없기 때문일까?

내용이 많아지게 되면 차이가 더 날지 궁금하다.

 

더보기

채찍피티에 따르면...

 

페이지에 로드해야 할 내용이 많아지면, priority 속성의 영향이 더 두드러질 수 있습니다. 이 속성은 브라우저가 해당 이미지를 더 빨리 로드하도록 우선순위를 높이는 역할을 하기 때문에, 다른 리소스들이 많을 경우 더 큰 차이를 만들어낼 수 있습니다.

다음은 이유입니다:

  1. 네트워크 자원의 경쟁: 페이지에 많은 리소스(이미지, 스크립트, 스타일 등)가 있으면 브라우저는 이 리소스들을 모두 다운로드해야 합니다. 이때 priority 속성이 없는 이미지라면 다른 리소스들과의 경쟁에서 우선순위가 낮아져 상대적으로 느리게 로드될 수 있습니다.
  2. 크리티컬 렌더링 경로: 브라우저는 LCP(Largest Contentful Paint)와 같은 중요한 렌더링 지표를 계산할 때 priority 속성이 있는 이미지를 더 빨리 로드하려고 합니다. 페이지 내용이 많아질수록, 이러한 중요한 요소를 먼저 로드해주는 것이 페이지 전체의 로딩 시간을 단축시키는 데 더 중요해집니다.
  3. 병목 현상: 페이지가 무거워질수록 브라우저는 리소스 로드 과정에서 병목 현상이 발생할 가능성이 큽니다. priority 속성은 이 병목 현상을 줄이는 데 도움이 될 수 있으며, 그 결과로 시간 차이가 더 커질 수 있습니다.

따라서, 페이지에 로드할 내용이 많아질수록 priority 속성을 사용했을 때와 그렇지 않았을 때의 로딩 시간 차이는 더 커질 가능성이 높습니다. 이를 확인하려면, 다양한 조건에서 테스트를 진행해보는 것이 좋습니다.

쓸데없는 이미지를 더 로드해봤다.

 

왼쪽은 with priority, 오른쪽은 without priority 조건이다

각각 FP 288.69ms LCP 1.48s, FP 481.57ms LCP 1.81s

 

with priority

우선순위 설정이 있을 때 네트워크 탭을 보면 다른 이미지들보다 우선해서 해당 이미지를 가져오는 걸 볼 수 있다. 

큐에 들어간 시간도 아주아주 빠르다.

 

priority 설정 없을 때

우선순위 설정 없이는 다른 이미지를 불러오고 난 뒤 순서에 따라 큰 이미지를 불러오는 걸 확인할 수 있다.

큐에 들어간 시간도 476.97ms가 된 것을 볼 수 있다.

 

priority 속성 하나에 따라 큰 차이를 만들 수 있는 게 신기하다

 

 

 

그렇다면 리소스 크기를 줄여서 시간도 줄여보자

태그를 보면 width height 설정이 2982, 1692로 설정된 것을 볼 수 있다

반면 왼쪽에서 표시되는 사이즈를 보면 339.73 * 160으로 훨씬 작아 이미지를 너무 크게 로딩하고 있음을 알 수 있다

문제는 Next 의 Image 컴포넌트에 크기 속성이 설정되지 않은 부분이다.

https://nextjs.org/docs/app/api-reference/components/image

 

Components: <Image> | Next.js

Optimize Images in your Next.js Application using the built-in `next/image` Component.

nextjs.org

 

참고해서 크기를 맞추고자 하는 부모 태그에 relative 속성을 주고 fill 속성을 추가했다.

2982, 1692 보다 훨씬 작은 크기로 불러오고 있다.

 

 

성능이 조금 올라갔다.

1.31s - 253.45ms

~=1.057s

 

결론

 

처음 상태(2.6412s )와 비교해 FP->LCP 시간을 59.98,  60% 감소시켰다

'Dev > 리팩토링' 카테고리의 다른 글

타이포랩 리팩토링: 가이드 페이지  (1) 2024.09.03