상세 컨텐츠

본문 제목

[Vite+tabler/icons-react] 성능 이슈 해결(청크 5,000개+ 요청 현상)

Programming/기타

by 겨리! 2025. 7. 19. 23:18

본문

 

 

 

Vite 기반의 프로젝트에서 tabler/icons-react 라이브러리를 사용하던 중 마주했던 문제를 정리해보고자 한다.

 

 

 

사내 UI 프로젝트에서 사용하고 있는 tabler/icons-react를 세팅 후 필요한 아이콘 몇 개를 import해서 사용하려고 했다.

그런데..웬걸 로컬 서버를 띄운 후 접속해보니 페이지 진입 속도가 너~~무 느렸다..!

너무 느려서 네트워크 탭을 확인해봤더니, 5,000개가 넘는 아이콘 청크를 전부 요청하고 있었다.

아이콘 몇 개만 사용했을 뿐인데...요청이 5,000개가 넘는다니...🙄 대환장

 

참고로 내가 사용한 라이브러리의 버전은 아래와 같다.

- Vite v5.4.17

- tabler/icons-react v.3.29

 

 

문제 상황

아래는 테스트용 코드인데,

아이콘 하나만 import 해도 전체 아이콘이 개별 청크로 쪼개져 모두 요청되는 이상한 현상이 발생했다.

// App.tsx
import { IconUser } from "@tabler/icons-react";

function App() {
  return <IconUser />;
}

 

위처럼 세팅한 후 로컬 서버를 띄우고 네트워크 탭을 열어보면, 수많은 요청이 쏟아진다.

아래 사진을 보면 5,854번의 요청이 찍힌 걸 확인할 수 있다..😮

 

 

원인

@tabler/icons-react의 export 구조

Tabler는 아이콘 5,000개가 넘는 아이콘을 다음과 같이 개별 ESM 모듈로 모두 export한다.

정말 많다...!

 

Vite의 ESM 사전 번들링 분석 방식

Vite는 성능 최적화를 위해 dev 서버 구동 시 ESM 모듈을 사전 분석(pre-bundling)한다. 

여기서 index.mjs에서 수천 개의 export가 존재하다 보니, "혹시라도 이 중 하나라도 쓸 수 있으니까"라는 이유로 모든 아이콘을 lazy chunk로 나누고 prefetch까지 해버린다.

위와 같은 이유로 아이콘을 하나만 사용하더라도 모든 .mjs파일을 개별로 요청하게 된다.

 

 

해당 현상에 대해 키워드로 구글링해보니 

Reddit과 tabler/tabler-icons 이슈 탭에서 관련 글과 해결 방법을 찾을 수 있었다.

(모두 극대노하고 있음)

 

✔ raddit

https://www.reddit.com/r/reactjs/comments/1g3tsiy/trouble_with_vite_tablericons_5600_requests/?rdt=50753

tabler-icons 이슈

https://github.com/tabler/tabler-icons/issues/1233

 

해결 방법

vite.config.ts에 alias 추가하기

// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      '@tabler/icons-react': '@tabler/icons-react/dist/esm/icons/index.mjs',
    },
  },
});

 

위와 같이 설정하면, Vite가 @tabler/icons-react 전체가 아닌, index.mjs 단일 파일만 참조하게 된다.

이렇게 하면 Vite가 개별 아이콘 파일들을 분석하거나 요청하는 일을 더 이상 하지 않게 된다.

 

이후 네트워크 탭을 다시 확인했을 때 요청이 20개로 줄어든 것을 확인할 수 있었다.

 

 

 

 

alias 설정 후 실제로 아이콘 import하면 어떻게 동작할까?

예를 들어 아래처럼 딱 하나의 아이콘을 import했다고 가정해보자.

import { IconUser } from '@tabler/icons-react';

 

Vite는 이걸 어떻게 처리할까?

alias 설정이 적용되어 있기 때문에,
Vite는 @tabler/icons-react 전체 구조를 분석하지 않고, index.mjs 파일 하나만 번들에 포함시킨다.
그 안에서 내가 import한 IconUser만 추적해서 번들에 포함하고, 나머지 아이콘은 건드리지 않는다.

 

 결과적으로 IconUser만 포함된 작은 chunk 하나가 생성되고, 5,000개가 넘는 .mjs 요청은 발생하지 않는다.

 

 

정리

 

 @tabler/icons-react는 구조상 모든 아이콘을 export하고 있어서 Vite의 번들러가 과잉 분석하게 된다.

 이때 alias를 통해 분석 대상을 index.mjs 하나로 제한해주면, Vite는 더 이상 수천 개의 파일을 청크로 나누지 않는다.

 alias 한 줄 설정만으로 .mjs 수천 개 요청을 막을 수 있다..!

 

 

관련글 더보기

댓글 영역