[IT 심층 분석]
프론트엔드 번들 용량이 폭발적으로 증가한 진짜 이유와 Tree Shaking 실패 원인 완전 해부
김민준 · IT 시스템 엔지니어|
신규 팀원이 개발한 피처 브랜치가 병합된 이후 갑자기 웹 앱의 초기 로딩 성능이 급격하게 저하되었다는 사용자 피드백이 쏟아졌습니다. Lighthouse 성능 점수가 93점에서 58점으로 추락했고 번들 분석 도구인 webpack-bundle-analyzer를 돌려본 결과 자바스크립트 번들 크기가 1.2MB에서 4.8MB로 4배 가까이 폭발적으로 증가해 있었습니다. 특별히 거대한 기능을 추가한 것도 아닌데 이런 현상이 발생한다는 것은 트리 쉐이킹 즉 사용하지 않는 코드를 자동으로 제거하는 빌드 최적화 과정이 어딘가에서 제대로 작동하지 않고 있다는 신호입니다.
번들 시각화 결과를 들여다보니 lodash 라이브러리 전체가 통째로 번들에 포함되어 있는 것을 발견했습니다. 팀원이 추가한 코드에서 단 세 개의 헬퍼 함수만을 사용하기 위해 lodash를 import했는데 방식이 문제였습니다. import _ from 'lodash' 방식으로 가져온 것이 원인이었습니다. 이렇게 전체 네임스페이스를 가져오는 방식은 Webpack이 과연 어떤 함수가 실제로 사용되는지 트리 쉐이킹 분석을 통해 추적하기가 매우 어렵습니다. lodash의 전체 소스가 단일 거대 파일인 CJS(CommonJS) 모듈로 묶여있는 경우에는 트리 쉐이킹이 아예 작동하지 않습니다.
이 문제를 해결하는 가장 즉각적인 방법은 Named import를 사용하거나 함수별 경로로 임포트하는 방식으로 바꾸는 것입니다. import { debounce } from 'lodash-es'(ES Module 버전) 또는 import debounce from 'lodash/debounce'처럼 함수 단위로 경로를 지정하면 Webpack static analysis가 해당 모듈만을 번들에 포함할 수 있게 됩니다. 장기적인 해결책으로는 babel-plugin-lodash를 빌드 파이프라인에 추가하여 전체 임포트 구문을 빌드 시 자동으로 함수별 임포트로 변환하도록 설정했습니다. 또한 유사한 제3자 라이브러리 전체를 대상으로 번들 크기 회귀를 방지하는 bundlesize CI 체크를 Github Actions에 추가했습니다. 이 조치들로 번들 크기는 다시 1.3MB 수준으로 안정화되었고 Lighthouse 점수도 91점을 회복했습니다.