Electron 앱 용량 줄이기 — 100MB에서 30MB로

게시일: 2025년 7월 29일 · 13분 읽기

사용자가 100MB 앱을 안 깔고 싶어한다

초기 Electron 앱의 크기가 100MB였다. 설치 시간도 오래 걸리고, 특히 느린 인터넷 환경의 사용자들이 "좀 더 작을 수 없나요?"라고 물어봤다.

의존성을 정리하고, 불필요한 부분을 제거했다. 이제 30MB다. 설치도 빠르고, 사용자 만족도도 올라갔다.

분석: 뭐가 용량을 먹나

<?xml version="1.0"?>
npm ls --depth=0

dependencies:
electron              180MB (Electron 자체)
node_modules/        90MB  (의존성)
  - lodash           4MB
  - moment          8MB
  - uuid            2MB
  - 기타            76MB

build artifacts      20MB
native modules       10MB

최적화 1: 불필요한 의존성 제거**

<?xml version="1.0"?>
// lodash 제거 → 네이티브 함수로 변경
import _ from 'lodash'

// Bad
_.pick(obj, ['a', 'b'])
_.omit(obj, ['c', 'd'])

// Good (최신 JavaScript)
const { a, b } = obj
const { c, d, ...rest } = obj

// moment 제거 → date-fns로 변경 (더 가벼움)
import { format, parse } from 'date-fns'

// uuid는 유지 (자체 구현은 위험)

// 결과: 12MB → 2MB

최적화 2: 언어 파일 제거**

<?xml version="1.0"?>
// electron-builder 설정에서 불필요한 로케일 제거
{
  "build": {
    "asarUnpack": [
      "node_modules/electron/dist/resources/locales/en*",
      "node_modules/electron/dist/resources/locales/ja*"
    ],
    "files": [
      "!**/locales/**/*",
      "!**/resources/**/*.lproj"
    ]
  }
}

// 또는 프로세싱으로 제거
import * as fs from 'fs'
import * as path from 'path'

function removeUnusedLocales() {
  const keep = ['en', 'ja', 'ko']  // 필요한 언어만
  const localesPath = path.join(
    __dirname,
    'node_modules/electron/dist/resources/locales'
  )

  fs.readdirSync(localesPath).forEach(file => {
    const lang = file.split('.')[0]
    if (!keep.includes(lang)) {
      fs.unlinkSync(path.join(localesPath, file))
    }
  })
}

// 효과: Electron 번들에서 30MB 절감

최적화 3: 폰트 서브셋팅**

<?xml version="1.0"?>
// 전체 폰트 파일은 거대함
// 필요한 글자만 추출

npm install -D fonttools

// subsetting script
#!/bin/bash
pyftsubset JetBrainsMono-Regular.ttf   --unicodes="U+0020-U+007E,U+00C0-U+00FF"   --output-file="JetBrainsMono-Regular-subset.ttf"

// CSS에서 사용
@font-face {
  font-family: 'JetBrains Mono';
  src: url('./fonts/JetBrainsMono-Regular-subset.ttf') format('truetype');
  font-display: swap;
}

// 효과: 폰트 파일 6MB → 1.5MB

최적화 4: Native 모듈 최소화**

<?xml version="1.0"?>
// 불필요한 옵션 의존성 제거
npm list --all | grep optional

// 선택적 의존성 건너뛰기
npm ci --no-optional

// 또는 package.json에서
{
  "optionalDependencies": {
    "sharp": "^0.32.0"  // 이미지 처리
  }
}

// electron-builder에서
{
  "build": {
    "nodeGypRebuild": false,
    "buildDependenciesFromSource": false
  }
}

// 효과: 불필요한 네이티브 바인딩 10MB 제거

최적화 5: 빌드 아티팩트 최소화**

<?xml version="1.0"?>
// .gitignore와 비슷하게
// electron-builder의 files 설정으로 제외

{
  "build": {
    "files": [
      "dist/**/*",
      "node_modules/**/*",
      "package.json"
    ],
    "extraMetadata": {
      "name": "my-app"
    }
  },
  "files": [
    "!**/*.map",           // Source maps 제거
    "!**/test/**/*",       // 테스트 파일
    "!**/node_modules/@types/**/*",
    "!**/*.ts",            // TypeScript 원본
    "!**/.gitignore",
    "!**/README.md",
    "!**/LICENSE"
  ]
}

// 효과: 5MB 절감

최적화 6: 코드 분할 및 동적 로드**

<?xml version="1.0"?>
// 큰 라이브러리는 필요할 때만 로드
async function loadPDFLibrary() {
  // 처음엔 로드 안 함
  const { PDFDocument } = await import('pdf-lib')
  return PDFDocument
}

// 또는 webpack/vite 설정
{
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          'pdf': ['pdf-lib'],
          'chart': ['chart.js']
        }
      }
    }
  }
}

체크리스트**

<?xml version="1.0"?>
// 체크리스트 (scripts/optimize.sh)
#!/bin/bash

echo "🔍 Analyzing app size..."
du -sh . | sort -hr

echo "📦 Checking dependencies..."
npm ls --all | head -20

echo "🗑️ Cleaning up..."
# 불필요한 파일 제거
rm -rf **/*.map
rm -rf **/.test.*
find node_modules -name "*.d.ts" -type f -delete

echo "✅ Done!"
npm run build:app

최종 결과**

마무리**

Electron 앱의 크기는 의존성 관리로 대부분 절감할 수 있다. 큰 라이브러리가 정말 필요한지, 더 작은 대안이 있는지 항상 질문해야 한다.

100MB에서 30MB로 줄이는 것만으로도 사용자 경험이 크게 개선된다. 다운로드도 빠르고, 설치도 빠르고, 앱 자체도 빠르다.

iL
ian.lab

실무 개발자입니다. 현장에서 겪은 문제와 해결 과정을 기록합니다. 오류 제보는 연락처로 보내주세요.