
📦 아이콘, 대체 넌 왜 이렇게 크니..
웹 성능 최적화: 아이콘 패키지 번들 크기 줄이기
2025년 9월 19일
웹 성능 최적화: 아이콘 패키지 번들 크기 줄이기
2025년 9월 19일
이전 글에서 문제 원인을 찾던 중 번들 크기를 분석하기 위해 @next/bundle-analyzer
를 사용했었습니다.
그 과정에서 생각보다 아이콘이 차지하는 비율이 꽤 크다는 사실을 발견했습니다.
아이콘 패키지는 크게 두 가지 요소를 가지고 있습니다.
스토리북에서는 이 tags를 이용해 “apple”이라고 검색하면 Apple 아이콘을 바로 찾을 수 있었습니다.
이 덕분에 팀원들이 아이콘을 빠르게 탐색할 수 있었죠.
실제 서비스 코드에서는 iconRegistry를 전혀 쓰지 않는데도, 번들에는 이 코드가 함께 들어가고 있었습니다.
하지만 이 기능은 아이콘을 사용하는 곳이 아닌 스토리북에서만 필요한 기능이였습니다.
즉, 아이콘을 사용하는 웹사이트에서는 사용하지 않는 코드가 번들 파일에 포함되지 않도록 설정해야했습니다.
여기서 떠오른 해결책은 바로 트리셰이킹입니다.
트리셰이킹은 사용하지 않는 코드가 번들 파일에 포함되지 않도록 코드를 제거하는 최적화 기법입니다.
예를 들어 수십 개 아이콘 중 + 아이콘 하나만 쓴다면, 최종 번들에는 + 아이콘 코드만 남고 나머지는 전부 제거됩니다.
이 과정을 통해 번들 크기를 줄일 수 있습니다.
저는 번들러로 Vite를 사용하고 있었는데, 여기서 중요한 옵션이 바로 preserveModules입니다.
이 옵션을 켜면 빌드된 결과물이 하나의 큰 파일로 합쳐지지 않고, 각각의 모듈이 독립적으로 유지됩니다.
이렇게 적용하면 하나의 큰 번들로 합쳐지지 않기 때문에, 실제 사용되는 아이콘만 딱 분리되어 포함되도록 만들 수 있습니다.
아이콘 컴포넌트는 DOM을 조작하거나 CSS를 불러오는 부수효과가 없습니다.
따라서 package.json에 다음과 같이 설정해 트리셰이킹을 더 확실히 동작할 수 있도록 설정하였습니다.
만약 iconRegistry가 필요하지 않은데 아래처럼 한꺼번에 가져오면, 모든 아이콘이 함께 번들에 포함될 수 있습니다.
이를 막기 위해 엔트리 포인트를 분리했습니다.
index와 registry를 각각 독립적인 진입점으로 설정해 실제로 필요한 곳에서만 import하도록 만들었습니다.
또한, vite에서 Multi-entry 설정을 하여 실제 아이콘 파일과 registry파일을 독립적인 진입점으로 인식할 수 있도록 설정해주었습니다.
최적화를 적용한 결과, 실제로 사용하는 아이콘만 번들에 포함되는 걸 확인할 수 있었습니다.
이전 작업은 그저 동작만 하는 코드들을 만들었다면 아번 작업을 통해 실제로 어떤 코드가 번들에 포함되고, 어떤 설정이 성능에 직접적인 영향을 미치는지 체감해 볼 수 있었습니다.
이번 최적화는 그런 의미에서 좋은 계기가 되었던 것 같습니다 😁