-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FE] 리소스 최적화 및 번들 크기 감소 #365
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
좋네요 어프루브 드리겠씁니다! 군더더기 없이 깔끔합니다 :) 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생하셨어요~ 빙봉뱅봉!! 🔮 모모 서비스 성능이 개선되는 것을 보니 기분이 좋아지네요 ㅎㅎ
501c427
to
1394c24
Compare
Test Results9 tests 9 ✅ 10s ⏱️ Results for commit 1394c24. |
관련 이슈
작업 내용
성능 개선 전
성능 개선 전에는 Lighthouse 성능 측정에서 데스크탑 기준 69점, 모바일 기준 45점을 기록했다.
성능 개선 후
성능 개선 후에는 Lighthouse 성능 측정에서 데스크탑 기준 90점, 모바일 기준 63점을 기록했다.
최종적으로 번들 파일이 코드 스플리팅되어 1.1 kB + 226 kB + 21.3 kB + 55.6 kB로 나뉘어 합계 304 kB가 되었다. (3.9 MB → 304 kB)
1. JS 리소스 크기 줄이기
1-1. aws cloudfront의 content-Encoding을 gzip에서 br로 변경
CloudFront 파일 압축 문제 해결
AWS는 기본적으로 br 압축 방식을 지원하며, 브라우저가 br를 지원하지 않는 경우에는 gzip을 제공한다. 하지만 테스트 과정에서 모든 브라우저에 대해 gzip 압축이 적용되는 문제가 발생하였다.
해당 문제를 해결하기 위해 CloudFront의 캐싱 정책을 점검하였고, 응답 헤더에 캐싱 정책이 제대로 설정되어 있지 않음을 발견했다. 이로 인해 gzip이 기본적으로 제공된 것으로 파악되었다. 캐싱 정책을 올바르게 적용한 후, br로 압축 방식이 변경된 것을 확인했다.
결과
br로 압축 방식이 변경된 것을 확인했으나, 번들 파일의 총 크기는 여전히 3.9MB로 동일했다. 이는 압축 방식에 따른 전송 크기 변화는 있지만, 번들 파일 자체의 크기에는 영향을 미치지 않기 때문이다. 브라우저가 파일을 다운로드할 때의 전송 데이터 양이 줄어들어, 네트워크 성능이 향상될 것이라고 예측한다.
1-2. Code splitting
모모 서비스에서 코드 스플리팅이 필요한 주요 이유는 페이지별 불필요한 리소스 다운로드로 인한 초기 로딩 속도 저하 문제 때문이다.
예를 들어, 약속 시간 조회 페이지에 방문한 사용자가 단순히 시간을 확인하려고 할 때, 다음과 같은 페이지들의 리소스를 모두 다운로드하게 된다. → 약속 시간 조회 페이지의 초기 로딩 시간이 길어지는 문제가 발생
이 페이지들은 사용자가 반드시 방문할지 알 수 없기 때문에, 모든 리소스를 미리 다운로드할 필요가 없다고 판단하였다. 따라서 코드 스플리팅을 통해 번들 파일의 크기를 분리하고, 각 페이지에 방문할 때만 필요한 리소스를 다운로드받도록 개선했다.
이를 위해 다음과 같은 webpack 설정을 적용했다.
SplitChunks: 코드 스플리팅을 자동화하기 위해
splitChunks
옵션에서chunks: 'all'
을 사용하여 중복된 코드나 공통 모듈을 별도의 청크로 분리했다.Output 설정: 각 번들 파일에 해시를 추가하여 캐싱 최적화를 적용했다.
contenthash
를 사용해 파일 내용이 변경될 때만 해시가 달라지도록 하여, 파일이 변경되지 않은 경우에는 브라우저가 캐시를 활용할 수 있도록 했다.또한,
dynamic import
,lazy loading
,Suspense
를 적용하였다. UX 개선을 위해 새로운 페이지의 리소스를 다운로드하는 동안 Loading fallback UI를 구성하여 사용자에게 로딩 상태를 안내할 수 있도록 했다.이로 인해 초기 로딩 속도가 개선되었고, 페이지 로드 시 불필요한 리소스 다운로드를 최소화함으로써 사용자 경험이 향상되었다.
2. 이미지 크기 줄이기
2-1. svg 파일 최적화
SVG 사용 이유
로고, 아이콘, 캐릭터와 같은 이미지 요소를 SVG로 사용하였다. 그 이유는 다음과 같다.
또한, 프로젝트에서 SVGR을 사용하여 SVG 파일을 React 컴포넌트처럼 import해서 사용하고 있다. SVGR은 SVG 파일을 React 컴포넌트로 변환하는 도구로, SVGO(SVG Optimizer)를 내장하고 있어 SVG 최적화 기능도 제공한다.
문제 상황
하지만, 몇 가지 원본 크기 자체가 1MB를 넘는 SVG 파일들이 4가지가 있었다. logo, logoSunglass, momoCharacter, questionMomoCharacter 파일들은 모두 Figma에서 SVG 파일을 바로 추출해서 사용했었다. 해당 이미지들은 Base64로 인코딩되어 SVG 파일 안에 인라인으로 포함되어 있었다. Base64 인코딩된 이미지 데이터는 파일 크기가 커지기 쉬운데, 이로 인해 SVG 파일 자체가 1MB 이상으로 비대해졌던 것이다.
문제 해결 과정
그래서 다음과 같은 방식으로 SVG 파일의 크기를 줄였다.
logo.svg
파일에서 Base64 데이터로 대체했다.결과
1MB 이상이었던 SVG 파일 4개의 크기를 줄였더니 bundle.js의 크기가 300 kB로 줄었다.
3. 사용하지 않는 폰트 제거하기
느린 4G 환경에서 모모 서비스를 사용해 보면, 폰트를 다운로드받는 데 상당한 시간이 소요되었다. (느린 4G 환경에서 약 13초 이상)
3-1. 꼭 필요한 Glyph만 포함하는 폰트 파일 만들기
웹 페이지에서 노출될 일이 없는 Glyph를 삭제하여 폰트 파일을 최적화했다.
Pretendard 공식 GitHub에서 제공하는 subset 폰트를 사용하였다.
또한, 이전에는 모든 폰트 크기를 포함한 글꼴을 사용하였지만, 서비스 내에서 300, 400, 500, 700의 네 가지 크기만 사용하고 있다는 것을 확인했다. 따라서, 필요한 폰트 크기만 남기고 나머지는 제거함으로써 폰트 파일의 크기를 줄였다.
결과
Lighthouse 성능 측정에서 데스크탑 기준 96점을 기록했다.
3-2. 폰트 preload 적용
폰트 preload는 웹 페이지 로딩 시 폰트를 미리 로드할 수 있게 하여 FOUT 현상을 방지한다.
webpack-font-preload-plugin을 사용하여 폰트를 preload하는 방식을 적용하였다.
subset 폰트로 교체한 후, Lighthouse 성능 측정에서 데스크탑 기준 96점을 기록했다.
하지만 폰트를 preload할 경우, 폰트가 bundle.js보다 먼저 로드되기 때문에 LCP 점수가 낮아지는 현상이 발생했다. 이러한 문제로 인해 폰트 preload 적용 여부에 대해 고민하게 되었다.
위와 같은 현상이 발생하여 폰트 preload 적용 여부를 고민하게 되었다. 폰트 깜빡임 현상을 개선하기 위해 preload를 적용할지, 아니면 preload를 적용하지 않고 Lighthouse에서 LCP 점수를 높일지를 두고 논의한 결과, 폰트 깜빡임을 해결하는 것이 더 중요하다고 판단했다.
따라서 LCP 점수가 다소 낮아지더라도 폰트 preload를 적용하여 폰트 깜빡임 현상을 제거하기로 결정했다.
특이 사항
참고 자료
자세한 내용은 작업 현황 정리 노션을 참고해 주세요. :)
리뷰 요구사항 (선택)