07 — 성능 & 메모리 (Performance & Memory)
이 챕터가 답하는 질문: 왜 Electron 앱은 빈 창 하나만 띄워도 100MB를 먹고 2초 만에 뜨는가? 그 비용을 어디까지 줄일 수 있나? 한 줄 답 (Pyramid Top): “Electron의 성능 문제는 공정한 비교가 어려운 데서 출발한다 — 브라우저는 이미 떠 있고 매번 fresh가 아니지만, Electron은 매번 Chromium + Node + V8을 새로 띄운다. 비용을 인정하고 (a) cold start 단계별로 깎고 (b) 프로세스 수를 통제하고 (c) V8 snapshot으로 평가 시간을 잘라내는 것 — 세 자리에서만 진짜 효과가 난다.”
이전 챕터(06 — 패키징 & 배포)가 사용자 PC에 어떻게 도착하는가를 다뤘다면, 이번 챕터는 도착한 뒤 얼마나 무거운가다. Electron이 “느리고 무거운 앱”이라는 평판을 받는 이유, 그 평판이 어디까지 공정한 비용이고 어디부터 해결 가능한 낭비인지를 가른다.
비용 구조 (Cost Anatomy)
세 개의 비용 축(시간 · 메모리 · 크기)이 서로 다른 단계에서 발생하고 서로 다른 기법으로 줄어든다. 이 챕터는 그 매핑이다.
Why — 왜 Electron 성능이 별도 챕터인가
세 가지 불공정한 직관이 거의 모든 비교에서 작용한다.
| 직관 | 실제 | 어디서 다루나 |
|---|---|---|
| ”Chrome으로 Slack 웹 띄우면 즉시 뜨던데 Electron Slack은 왜 느려?” | 브라우저는 이미 떠 있다 (warm). Electron은 매번 Chromium + V8 + Node를 fresh로 부팅한다. | 01 |
| ”100MB짜리 앱 = 코드가 100MB” | Electron 코어가 이미 ~100MB. 앱 코드는 그중 1-5%. 줄일 곳과 못 줄일 곳이 다르다. | 03 |
| ”메모리 누수 = 변수 끌어안고 있음” | 99%는 닫힌 창의 webContents 참조를 Main이 잡고 있는 것. JS 변수보다 프로세스 객체가 진짜 leak. | 06 |
이 챕터를 끝내면 *“Electron이 느리다”*가 *“어느 단계에서 얼마나 느린지”*라는 측정 가능한 질문으로 바뀐다.
본문 6개 — 인덱스
| # | 문서 | 한 줄 답 | 핵심 키워드 |
|---|---|---|---|
| 01 | Startup time | Cold start = 프로세스 fork → Chromium init → V8 시작 → JS 평가 4단계의 합. 측정 → 단계별로 깎기. | app.getCreationTime · performance.mark · ready-to-show · 단계별 budget |
| 02 | Memory footprint | 메모리 = 프로세스 수 × 한 프로세스 비용. 창을 늘리지 말고 재사용하라. RSS vs PSS의 함정. | RSS · PSS · process per window · helper · process.memoryUsage |
| 03 | Bundle size | 100MB+ 배포의 출처 — Electron 자체가 100MB이고 나머지는 우리 책임. asar 압축, npm prune, minify. | asar · electron-builder files · npm prune · two-package.json · minify |
| 04 | V8 snapshot | V8 snapshot으로 평가 시간을 미리 잘라낸다 — Atom·VS Code가 쓰는 기법. v8-compile-cache는 간이판. | v8-compile-cache · electron-link · startup snapshot · mksnapshot |
| 05 | GPU & Rendering | 하드웨어 가속은 대부분 빠르지만 가상화·구형 GPU·일부 드라이버에서는 오히려 느리다 — 끄는 것도 카드다. | disableHardwareAcceleration · GPU process · skia · compositor · CSS will-change |
| 06 | Leaks & Profiling | Renderer 누수는 DOM/listener, Main 누수는 닫힌 창 참조. heap snapshot으로 잡고 process.memoryUsage로 감시. | heap snapshot · detached DOM · destroyed webContents · listener leak · ipc.handle 누적 |
What — 6개 문서 한 줄 결론
| # | 문서 | 한 줄 답 |
|---|---|---|
| 01 | Startup time | Cold start를 4단계로 분해하고 단계마다 다른 기법을 쓴다 — fork는 못 줄여도 JS 평가는 절반 자른다. |
| 02 | Memory footprint | ”프로세스를 늘리지 마라”가 1순위 — 창 1개 ~80MB라 5창 = 400MB이고, 사용자 OS의 RAM 전체 점유율로 보인다. |
| 03 | Bundle size | Electron core ~100MB는 못 줄인다. 그 위에 얹는 우리 코드+node_modules가 진짜 줄일 자리. |
| 04 | V8 snapshot | JS를 미리 컴파일해서 직렬화 — 매 시작마다 parse/compile 비용을 0으로 만든다. Atom이 발명, VS Code가 정제. |
| 05 | GPU & Rendering | 가속이 항상 정답은 아니다 — 가상 머신·원격 데스크톱·일부 Linux에서는 끄면 빨라진다. chrome://gpu로 확인. |
| 06 | Leaks & Profiling | Renderer는 Chrome DevTools heap snapshot으로, Main은 직접 process.memoryUsage 모니터링으로 잡는다. |
How — 어떻게 읽나
- “앱이 뜨는 데 5초 걸린다”: 01 → 04. 측정 먼저, snapshot은 그 다음.
- “Activity Monitor에 helper가 10개나 뜬다”: 02 → 06. 프로세스 수 통제 + 닫힌 창 참조 찾기.
- “설치 파일이 250MB”: 03만. asar + prune + files glob.
- “가상 머신에서 화면이 깜빡인다”: 05만.
disableHardwareAcceleration. - “메모리가 시간 지나면 계속 늘어난다”: 06. heap snapshot 2장 비교.
What-if — 이 챕터를 건너뛰면
- 시작 시간 무관심: 사용자가 5초 흰 화면을 보고 “앱이 죽었나?”라고 생각한다. 신뢰가 한 번에 깨진다.
- 메모리 무관심: Slack·Discord·VS Code가 다 깔린 PC에서 우리 앱만 2GB를 먹어 사용자가 우리만 끈다.
- 번들 크기 무관심: 첫 다운로드 250MB → CDN 비용 + 모바일 hotspot 사용자 이탈.
- V8 snapshot 무관심: Atom이 그것 때문에 망했다 — 시작 시간이 점점 느려져 VS Code에 밀린 한 원인.
- GPU 무관심: 회사 VDI 환경에서 화면이 깜빡여 전사 도입 거부.
- Leak 무관심: 사용자가 주에 한 번 앱을 재시작해야 하는 백그라운드 앱이 된다.
Insight — 한 단락 이야기
“느린 앱”의 평판은 절반은 사실이고 절반은 부당하다
Electron이 “느리고 무거운 앱의 대명사”가 된 데에는 두 가지 진실이 섞여 있다. 사실: Chromium + V8 + Node를 매번 부팅하면 그 자체가 50ms~300ms씩 들고, 프로세스마다 ~80MB의 메모리를 먹는다 — 이건 기술의 본질 비용이다. 부당함: 브라우저는 항상 warm이고 공유 프로세스를 쓰지만, Electron은 항상 fresh고 전용 프로세스다. “Slack 웹 vs Slack Electron”의 비교는 처음부터 공정하지 않다. 그럼에도 — VS Code가 1초 안에 뜨고, Discord가 사용자 1억 명 위에서 데스크톱 표준이 된 사실은 — Electron의 비용이 해결 가능한 범위 안에 있다는 증거다. 이 챕터는 어디까지가 본질이고 어디부터가 게으름인지를 가른다.
Mermaid 4색 규약
한 단락 요약
Electron 성능은 세 축(시간·메모리·크기)에 각각의 비용 구조가 있다. 시간은 4단계 cold start로 분해되고(01), 메모리는 프로세스 수 × 단가로 보이고(02), 크기는 코어 고정 + 우리 책임으로 갈린다(03). 그 위에 V8 snapshot(04)·GPU 정책(05)·leak 프로파일링(06)이 가산 도구로 붙는다. 이 챕터를 끝내면 “Electron이 무겁다”가 *“내 앱의 어느 단계가 얼마나 무거운지 측정했고, 어디까지 줄일 수 있는지 정했다”*라는 엔지니어링 문장으로 바뀐다. 다음 챕터(08 — 생태계 & 대안)는 이 비용이 도저히 안 맞을 때 어떤 대안(Tauri·Wails·PWA)이 어떤 트레이드오프로 답하는지 본다.