-
Notifications
You must be signed in to change notification settings - Fork 0
FrontEnd 성능 개선기
작성자 : 김동규
알림 페이지는 진재님이 SSE 작업 중이시니 끝나시면 연동하자..
통계 히스토그램 컴포넌트는 UI 구현했으니 승재님의 API 작업 완료되면 연동하면 되겠고..
그 동안 뭐하지???
라이트 하우스 한번 찍어보자!
성능 측정 항목 대부분의 시간이 너무 오래 걸리는 것을 발견..
사용자가 빠르게 콘텐츠를 인식할 수 있도록 성능 개선의 필요성을 느껴버렸다.
내 성격 상 절대 못지나치지. 개선해보자 🔥
BundleAnalyzerPlugin
웹팩 플러그인을 설치해서 번들 분석을 해봤다.
엥.. react-icons
너 뭐야..?
react-icons
라이브러리를 사용하여 애플리케이션에 적용한 아이콘은 단 두가지 밖에 없다.
그런데 쓸데없이 이만큼 차지하고 있다니..
react-icons
는 icon 종류별로 구분되어 있으며, 종류별로 하나의 js 파일에 아이콘 전체를 포함하고 있다.
- 따라서 빌드 시 해당 파일이 전체가 포함이 되기 때문에 번들 사이즈가 커지게 된다.
@react-icons/all-files
라이브러리는 아이콘 별로 js 파일을 가지고 있다.
- 따라서 빌드 시 트리 쉐이킹 방식으로 인해 더 적은 크기의 번들을 만들게 된다.
다시 번들 분석해보자.
❗️ node_modules 번들 사이즈가 3.53 MB에서 1.27 MB로 줄었다!!
흠.. 그런데 메인 페이지에서는 사용하지도 않는 chart.js
등 라이브러리가 많은 크기를 차지하고 있다.
각 페이지들을 lazy
와 Suspense
를 사용해 필요할 때만 불러오도록 했다.
const HomePage = lazy(() => import("@pages/HomePage"));
const ChallengePage = lazy(() => import("@pages/ChallengePage"));
const RecordPage = lazy(() => import("@pages/RecordPage"));
const ProfilePage = lazy(() => import("@pages/ProfilePage"));
const FollowPage = lazy(() => import("@pages/FollowPage"));
const LoginPage = lazy(() => import("@pages/LoginPage"));
const JoinPage = lazy(() => import("@pages/JoinPage"));
const StaticsPage = lazy(() => import("@pages/StaticsPage"));
const SearchPage = lazy(() => import("@pages/SearchPage"));
...
<Suspense fallback={<div>loading..</div>}>
<Routes>
{/* Home */}
<Route path={RoutePath.HOME} element={<HomePage />} />
<Route path={RoutePath.CHALLENGE} element={<ChallengePage />} />
<Route path={RoutePath.RECORD} element={<RecordPage />} />
{/* Search */}
<Route path={RoutePath.SEARCH} element={<SearchPage />} />
{/* Statics */}
<Route path={RoutePath.STATICS} element={<StaticsPage />} />
{/* Profile */}
<Route path={RoutePath.PROFILE} element={<ProfilePage />} />
<Route path={RoutePath.LOGIN} element={<LoginPage />} />
<Route path={RoutePath.JOIN} element={<JoinPage />} />
<Route path={RoutePath.SEARCH} element={<SearchPage />} />
<Route path={RoutePath.FOLLOW} element={<FollowPage />} />
</Routes>
</Suspense>
...
다시 번들 분석!!
위 번들에서 메인 페이지에 요청되는 번들은 index.js
와 744.js
뿐! 훨씬 가벼워졌다.
❗️ 메인 번들인 index.js
의 크기가 307.19 KB에서 10.2 KB로 확연히 줄어든 것을 볼 수 있다.
enum
을 사용하면 번들 사이즈가 증가한다.
트리 쉐이킹이 되지 않기 때문이다!! (하지만! 우리가 사용하는 Webpack 번들러에서는 지원이 된다.)
그럼에도 enum
을 const
와 union type
으로 전부 변경함으로써 번들 사이즈를 줄일 수 있었다.
그 이유는 const
+ union type
의 빌드 코드보다 enum
빌드 코드가 확연히 많기 때문이다.
// constants/enum.ts
export enum RoutePath {
HOME = "/",
STATICS = "/statics",
SEARCH = "/search",
PROFILE = "/profile",
CHALLENGE = "/challenge",
RECORD = "/record",
LOGIN = "/login",
JOIN = "/join",
FOLLOW = "/follow",
};
...
이랬던 코드를 아래와 같이!
// constants/enum.ts
export const RoutePath = {
HOME: "/",
STATICS: "/statics",
SEARCH: "/search",
PROFILE: "/profile",
CHALLENGE: "/challenge",
RECORD: "/record",
LOGIN: "/login",
JOIN: "/join",
FOLLOW: "/follow",
} as const;
export type RoutePath = typeof RoutePath[keyof typeof RoutePath];
...
그 결과..
❗️ 메인 번들(index.js) 사이즈가 10.2 KB에서 7.79 KB로 줄었다!
그럼 이 기세를 이어 이미지도 최적화해보자.
JPG, PNG 등 이미지 파일들을 WebP 파일로 변환하여 크기를 줄였다.
- PIXLR 사이트에서 쉽게 변환할 수 있다.
- 그래서 전부 수동으로 변경했다..
👍 전제 번들 사이즈가 3.83 MB에서 1.68 MB로 줄어들었다.
👍 홈 페이지 기준 메인 번들(index.js
)이 307.14 KB에서 7.79 KB로 줄어들었다.
👍 Speed Index가 7.9 초에서 0.6 초로 줄어들었다.
👍 Total Blocking Time이 240 밀리초에서 130 밀리초로 줄어들었다.
Time to Interactive, Largest Contentful Paint 성능 요소는 크게 줄이지 못했다.
한번에 여러 데이터를 다른 API를 통해 각각 응답받기 때문에, 서버에서의 모든 데이터 응답 시간이 느려지는 요인이 큰 것 같다.
이 부분을 제외하고도 여러 문제점들을 분석하고 개선해보자! 🔥
그리고 현재는 홈 페이지에 대해서만 성능 분석 및 개선을 수행했다.
다른 페이지들에 대해서도 얼른 해보고 싶다.
- Date 객체가 내 PC 날짜를 참조하는거였어..?
- FrontEnd 성능 개선기
- Google OAuth 프론트 연계
- HTTPS 보안 등급 A+ 받기
- URL Parameter routing 트러블 슈팅
- Immer.js 도입기
- Request Header의 특정 헤더값이 확인이 안되는 경우
- FrontEnd 성능 개선기 두번째 (네트워크 Waterfall 발생)
- 실시간 알림을 위한 SSE 도입기
- Fitory 검색페이지 개발 & 성능 개선기
- Index를 이용한 DB 성능 개선 일지
- Full Text Search를 이용한 DB 성능 개선 일지
- 22.11.09. Week1 멘토링
- 22.11.11. Week1 마스터클래스 리뷰
- 22.11.16. Week2 멘토링
- 22.11.26. Week3 멘토링
- 22.11.30. Week4 멘토링