본문으로 건너뛰기

[Open WebUI] xlsx 라이브러리 동적 로딩으로 번들 868KB 감소

PR 링크: open-webui/open-webui#20203 상태: Merged | 변경: +10 / -20

들어가며

Open WebUI의 FileItemModal 컴포넌트에서 Excel/CSV 파일 미리보기를 위해 xlsx 라이브러리를 정적으로 import하고 있었다. 이 라이브러리는 868KB로 상당히 크지만, Excel 파일을 열지 않는 대부분의 사용자에게는 불필요한 코드다. 이 PR은 xlsx를 동적 import로 전환하여 초기 번들 크기를 줄인다.

핵심 코드 분석

Before: 정적 import

import * as XLSX from 'xlsx';

After: 동적 import + 타입만 정적 import

import type { WorkBook } from 'xlsx';

실제 사용 시 동적 로딩

const loadExcelContent = async () => {
    try {
        excelError = '';
        const [arrayBuffer, { read }] = await Promise.all([
            getFileContentById(item.id),
            import('xlsx')
        ]);
        excelWorkbook = read(arrayBuffer, { type: 'array' });
        // ...
    } catch (error) {
        excelError = $i18n.t('Failed to load Excel/CSV file.');
    }
};

const renderExcelSheet = async () => {
    if (!excelWorkbook || !selectedSheet) return;
    const worksheet = excelWorkbook.Sheets[selectedSheet];
    const XLSX = await import('xlsx');
    const range = XLSX.utils.decode_range(worksheet['!ref'] || 'A1:A1');
    // ...
};

API 함수 반환 타입 변경

// Before
return await res.blob();

// After
return await res.arrayBuffer();

왜 이게 좋은가

  1. 868KB 번들 감소: 초기 로딩에서 제외되는 코드양이 상당하다. 특히 모바일 환경에서 체감 효과가 크다.
  2. 병렬 로딩: Promise.all로 파일 데이터와 xlsx 라이브러리를 동시에 로딩하여 대기 시간을 최소화한다.
  3. 타입 안전성 유지: import type으로 타입 정보는 빌드 타임에 사용하면서, 런타임 코드는 동적으로 로딩한다.
  4. i18n 에러 메시지: 파일 로딩 실패 시 다국어 지원 에러 메시지를 제공한다.

참고 자료

댓글

관련 포스트

PR Analysis 의 다른글