-
[Portfolly] 메인 페이지 Lighthouse 분석Studying/Proj 과정 2023. 8. 1. 14:02
들어가면서...
Portfolly 메인 페이지 Lighthouse를 분석하고 추후 리팩터링 계획을 자세하게 세워보려고 합니다.
현업에서는 딱히 Lighthouse 점수를 깐깐하게 따져가며 개발하지 않는다지만, 최적화를 학습하고 싶다면 객관적인 지표를 제공하고 자세한 개선 방법을 안내해서 좋은 것 같습니다!
Lighthouse 점수
그렇게 나쁜 점수는 아닙니다. 그런데 그럴 수밖에 없는 게, 메인 페이지에 마땅한 자료가 없습니다. 게시물 테스트 한다고 몇 개 올려놓은 포트폴리오가 전부이고, 계속해서 동적으로 바뀌는 컴포넌트라든가 큰 비용이 들만한 것들이 없어서 그런 듯 합니다.
그래도 일단 부족한 부분은 있다고 하니 알아보겠습니다.
아래 지표에서 붉게 표시된 부분에 집중하겠습니다.
- Largest Contnetful Paint(LCP)
화면 내에 있는 가장 큰 이미지나 텍스트 요소가 렌더링되기까지 걸리는 시간을 나타냅니다.
Portfolly 메인 페이지의 경우 1.5초가 걸렸습니다.
이 지표는 고화질 포트폴리오 파일을 전시하는 Portfolly 홈페이지에서 특히 신경써야 할 부분이라고 생각합니다.
현재는 테스트 용으로 올려둔 이미지가 전부지만, 실제 배포했다고 가정했을 때 각종 고화질 파일을 전부 1초가 넘은 뒤에 렌더링한다면 사용자 경험은 급격히 저하할 것입니다.
페이지 로드 과정에서 발생하는 예기치 못한 레이아웃 이동을 측정한 지표입니다.
레이아웃 이동이란, 화면상에서 요소의 위치나 크기가 순간적으로 변하는 것을 말합니다.
사용자 경험을 망치는 건 이것도 꽤 큰 몫을 한다고 생각합니다. 각종 홈페이지들에서(특히 쇼핑) 늦게 렌더링된 컴포넌트들에 밀려서 잘못된 아이템을 클릭하고 페이지가 이동되었을 때 되게 짜증납니다.
이건 아마 포트폴리오 목록 데이터가 비어있을 때를 고려하지 않고 width, height 등을 설정해서 그런 것 같습니다.
문제점과 해결법
Lighthouse가 제공하는 문제점과 해결법에 대해 알아보겠습니다.
Diagnostics는 로드 속도와 직접적인 관계는 없지만, 성능과 관련된 기타 정보를 보여준다고 합니다.
Avoid large layouts shifts
예상했던 대로 포트폴리오 목록 비동기 데이터를 불러오는 과정에서 shift가 일어난다고 합니다.
Header에 Community 버튼과 로그인 버튼 사이에도 발생한다고 하는데, 제가 생각하기엔 아주 미세해서...
하지만 바꾸는 게 그렇게 어렵진 않으니 다음부터 꼭 고려하면 좋겠습니다.
일단 CLS 문제는 간단하게 CSS만 수정하면 되는 경우가 많다고 생각합니다. 저의 경우 width: fit-content를 단독으로 많이 사용했는데 그 습관을 좀 고치면 될 것 같습니다.
CLS를 개선하는 방법은 다양한 것들이 있지만, 당장 저희 Portfolly에서의 문제를 해결한 방법에 대해서만 적겠습니다.
min-height, min-width 사용하기
포트폴리오 목록, 헤더 버튼 2가지 모두 해결할 수 있는 핵심 방법입니다.
그냥 고정된 height과 width를 정해두면 됩니다. 컴포넌트가 렌더링되지 않아서 빈 공간이 생기는 것이니, 빈 공간을 감싸는 컴포넌트에 고정 크기를 정해두는 겁니다.
예를들어 포트폴리오 목록의 경우, <Wrapper> 의 스타일에 2개 버튼이 모두 렌더링 되었을 때 길이를 min-width로 설정해두면, 로그인 버튼이 한박자 늦게 렌더링 되었을 때 Community 버튼이 밀려날 일이 없습니다.
<Wrapper> // min-height: 300px; 으로 설정 <PortfolioList /> </Wrapper>
그 외 더 많은 해결법은 아래를 참고하면 좋습니다.
Preload Largest Contentful Paint image
가장 큰 크기의 이미지가 처음 렌더링되기까지 1.5초가 걸린다는 지표를 봤습니다.
이에 대한 해결책으로 Lighthouse는 크기가 큰 리소스의 경우 Preload, 즉 미리 로드하는 방식으로 성능을 향상시키라고 추천합니다.
리소스를 미리 로드하면, 브라우저 메인 렌더링이 시작되기 전에 브라우저가 리소스를 초기에 다운로드 받도록 트리거를 발동시켜 해당 리소스를 더 일찍 사용할 수 있게 됩니다. 그러면 크기가 큰 이미지가 가장 늦게 화면에 뜰 일도 줄어들 겁니다.
리소스를 미리 로드하는 방법
방법은 아주 아주 간단합니다. 바로 프리로드 태그를 추가하는 것입니다.
<link <!-- indicate preload --> rel="preload" <!-- as is required and indicates we are preloading an image --> as="image" <!-- image src --> href="wolf.jpg" <!-- optional: the responsive image srcset --> imagesrcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w">
위 구문과 같이 rel="preload" 속성을 추가하면 페이지 요청 시 해당 자원을 우선적으로 로드합니다.
그런데 혹시 srcset 속성을 사용해 화면 크기 별 이미지 크기를 조정한다면, 고려할 수 있는 모든 이미지 크기를 추가해야 합니다. 그렇지 않으면 잘못된 이미지를 프리로드 하게 되고, 페이지 속도만 느려지는 결과를 초래한다고 합니다.
자세한 내용은 아래 게시물에서 설명합니다.
Preconnect to required origins
직역하자면 써드파티 자원을 요청할 때 사전 연결을 하라고 합니다.
그리고 아래 사전 연결을 추천하는 origin url이 있는데 AWS S3 스토리지 주소네요.
Preconnect란, 다른 사이트에 저장된 자원(storage 외에도 Facebook, YouTube 임베딩 등)을 가져올 때 브라우저에서 주요한 써드파티 연결 순위를 지정하는 겁니다.
특히 써드파티 origin은 알고있지만, 실제 리소스 자체가 뭔지 모를 때 유용한 기법이라고 합니다. 페이지가 다른 origin에 연결하려고 하며, 이 프로세스를 가능한 빨리 시작해야한다는 사실을 브라우저에게 알려줍니다.
아마 저 스토리지 주소가 포트폴리오 목록 이미지 중 크기가 가장 큰 이미지 같습니다.
저걸 고치는 것도 좋겠지만, 사실 이미지 사이즈 최적화를 한다거나 다른 방법을 찾고,
저의 경우 '포트폴리오 상세 보기' 화면이나 Video 카테고리 포트폴리오 목록을 불러올 때 유튜브 영상 썸네일 로딩이 너무 오래 걸려서 유튜브 임베딩을 사전 연결 하면 더 좋을 것 같습니다.
장법은 Preload와 마찬가지로 간단합니다.
<link rel="preconnect" href="https://example.com">
위와 같이 사전 연결하고 싶은 origin 주소를 preconnect 하겠다는 구문을 추가하면 됩니다.
Chrom for Developers에 따르면, 더 포괄적으로 성능을 향상하는 preload를 사용하는 게 좋지만, 먼저 말했듯 "가져오는 데이터가 어디서 왔는지 알지만 무엇을 가져오는지 알 수 없을 때" preconnect를 사용하는 게 좋다고 합니다.
더 자세한 내용은 아래 참고 사이트를 참고 부탁드립니다.
Properly size images
드디어 이미지 크기에 대한 최적화를 진행하라는 경고가 나왔습니다!
이건 '프론트엔드 성능 최적화 가이드' 도서에서도 특히 여러번 펼쳐 본 챕터라 잘 알겠습니다.
렌더링 크기(Rendering size)에 비해 원본 이미지 크기(Intrinsic size)가 불필요할 정도로 큰 문제입니다.
Portfolly 사이트의 경우,
썸네일 중 가장 큰 이미지의 경우 어마무시하게 크기 차이가 나는 걸 확인할 수 있습니다.
이런 경우 Imigix CDN을 사용해 서버 ->
클라이언트로 이미지를 받아오기 전에, 이미지 CDN 통해 사이즈 변경
(다양한 크기의 디스플레이 지원을 위해 넉넉하게 이미지 사이즈를 렌더링 사이즈 2배 정도로 변경) ->
클라이언트로 보내주면
원본 사이즈가 줄어들어 렌더링 속도가 빨라집니다.
혹은, <img> 태그의 srcset을 사용해 화면 크기 별 이미지 사이즈를 미리 다 정해주는 방법도 있습니다.
화면 사이즈에 따라 브라우저가 로드할 가장 적절한 버전의 반응형 이미지를 선택합니다.
Serve images in next-gen formats
혹은 아예 이미지 포맷을 바꿔버리는 방법도 있습니다.
그런데 저는 썸네일은 이미지 CDN으로 사이즈 최적화를 하고,
포트폴리오 상세보기 페이지에 들어갔을 때 본문에 삽입된 이미지 포맷을 변경하는 식으로 최적화를 진행하면 좋을 것 같습니다.
썸네일 이미지는 어차피 크기가 작아서 화질이 크게 걱정 안되는데,
상세보기 페이지에 들어가서 크게 보는 포트폴리오 이미지는 용량을 줄이되, 품질도 어느정도 유지되어야 하기 때문에 .webp 확장자로 바꾸면 좋을 것 같습니다.
마치면서...
이 지표를 토대로 Portfolly 프로젝트를 리팩터링 하는 과정을 더 기록해보겠습니다.
사실 UI/UX도 사용자 친화적으로 더 수정을 거치고 싶은데다가, 리팩터링도 개인 활동으로 이어질 것 같아서, Firebase 서버를 구축한 다음 기존 코드 기반으로 다시 홈페이지를 구축해볼 계획입니다.
Lighthouse를 분석하면서, 다음부터는 다 구현한 뒤에 잘못된 걸 알아차리고 고칠 일 없게 처음부터 자잘한 CSS나 렌더링 최적화를 잘 적용해야겠다는 기본 틀을 가지게 되었습니다.
참고하면 더 좋은 자료
'Studying > Proj 과정' 카테고리의 다른 글
[Portfolly] 메인 페이지 UI/UX를 개선해보자(feat. mobbin) (0) 2023.12.24 [Portfolly] react-query로 불필요한 서버 요청 감소하기 (0) 2023.12.13 [Portfolly] 프로젝트를 마치며 (0) 2023.07.27 [Portfolly] 코드 Depth를 최대한 줄여보자 (0) 2023.07.27 [Portfolly] KISS 원칙으로 코드를 바꿔보자 (0) 2023.07.27