[성능 개선] 홈 화면 성능 개선하기: 1. 번들링 크기 줄이기

HBSPS·2023년 12월 18일
0

AlgoITNi

목록 보기
1/13

네이버 부스트캠프 8기 그룹 프로젝트로 AlgoITNi라는 프로젝트를 진행했다.

GitHub 보러가기

동료들과 함께 소통하며 알고리즘 학습을 할 수 있는 플랫폼을 만들고자 했으며 이를 위해

  • WebRTC를 이용한 실시간 P2P 화상 채팅
  • Socket을 이용한 실시간 채팅
  • 코드 공동편집
  • 클라우드 저장 및 불러오기
  • 클로바 X를 이용한 인공지능 질문

등의 기능을 구현하게 되었다.

이 과정에서 다양한 시도들이 있었으며 그 중 하나인 홈 화면 성능 개선하기에 대해 정리해본다.

시작하며

홈 화면 성능을 개선하기로 한 이유는 단순하지면 명확하다.
홈 화면은 사용자가 우리 서비스에 접근할 때 가장 먼저 접근하는 곳이기 때문이다.
홈 화면에서 빠른 응답 속도를 통해 좋은 UX를 제공한다면 사용자의 입장에서 우리 서비스를 긍정적으로 생각할 수 있기 때문이다.
또한, 대부분의 로직은 Room 안에 있기 때문에 불필요한 코드는 Home에 필요가 없었다.
성능 분석 및 최적화에 관심이 있었기 때문에 이번에 새롭게 배운 내용들을 적용해보고 싶었다.

번들링 크기 줄이기

(개발환경 Lighthouse)

첫 시작은 빌드 과정에서 위와 같은 경고로부터 시작한다.

위의 경고를 해석해보면 단일 청크의 크기가 500KB를 초과한다는 내용이다.
이를 위해서 동적 import를 통한 코드 스플리팅 또는 rollupOptions를 이용해 limit를 높이는 것을 제안하고 있다.
(rollupOptions를 수정하라는 추천도 있지만 단순히 경고 기준인 500KB를 1MB로 증가시키는 등의 방법이기 때문에 실질적인 도움이 되지않는다고 판단했다)

우선 빌드 결과물이 왜 이렇게 커졌는지 분석하기 위해 Vite 번들 분석 도구를 활용해야 한다.

npx vite-bundle-visualizer

번들링 크기를 확인해보면 코드 하이라이팅을 위한 highlight.js 라이브러리가 번들링 크기의 50% 이상을 차지하고 있음을 알 수 있다.
그 이유는 highlight.js에서는 많은 언어를 지원하기 때문에 우리가 사용하지 않는 언어에 대한 정보도 함께 번들 과정에 포함되기 때문이다.

기존 코드는 아래와 같다.

import hljs from 'highlight.js';

const highlightCode = (language: string, code: string) => {
  return hljs.highlight(code, { language }).value.replace(/" "/g, '  ');
};

export default highlightCode;

highlight.js 전체를 import 하여 사용하고 있는 것을 볼 수 있다.
이를 해결하기 위해 현재 서비스에서 사용하는 언어만 import 하도록 수정해야 한다.
단, 향후 서비스에서 어떤 언어를 지원할지 모르기 때문에 config 파일을 생성하여 import를 관리할 수 있도록 했다.
트리 쉐이킹을 통해 필요한 언어 정보만 가져오되 추후 언어 추가에 유연하게 대응하기 위함이었다.

import codeHighlighter from 'highlight.js/lib/core';
import python from 'highlight.js/lib/languages/python';
import javascript from 'highlight.js/lib/languages/javascript';

codeHighlighter.registerLanguage('python', python);
codeHighlighter.registerLanguage('javascript', javascript);

export default codeHighlighter;
import codeHighlighter from "@/configs/highlightCodeConfig";

const highlightCode = (language: string, code: string) => {
  return codeHighlighter.highlight(code, { language }).value.replace(/" "/g, '  ');
};

export default highlightCode;

위와 같이 서비스에서 실제로 사용하는 언어만 import 할 수 있도록 수정했다.
만약, 새로운 언어가 추가된다면 import만 하나 추가해준다면 해당 언어도 적용할 수 있다.

결과

결과적으로 highlight.js의 불필요한 부분을 제거할 수 있었고 다음과 같은 결과를 얻을 수 있었다.

  • 빌드 시간: 6.07s → 3.14s (약 48% 감소)
  • 청크 크기: 1,285KB → 402KB (약 68% 감소)

전역 상태 관리 라이브러리 선택

전역 상태 관리 라이브러리를 선택하는 과정에서도 번들링 크기를 고려하게 되었다.

종류recoilzustand
번들 크기2.17MB187KB
상태관리 방식상태 위주의 관리상태와 상태를 변경하는 함수를 따로 작성하여 관리

추후 상태를 변경하는 action이 많아지면 recoil 역시 custom hook을 자주 사용하게 되므로, 번들 크기가 작고 상태와 상태변경 함수가 분리된 zustand를 사용하게 되었다.

profile
대체로 맑음

0개의 댓글