refactor: 메모리 누수 정리 및 타이머 관리 개선, 이벤트 리스너 제거 함수 추가

This commit is contained in:
“hyeonggkim”
2025-11-14 16:47:38 +09:00
parent ffa89ffbb6
commit ae7fb5fd60
10 changed files with 283 additions and 12 deletions

92
MEMORY_LEAK_ANALYSIS.md Normal file
View File

@@ -0,0 +1,92 @@
# 메모리 누수 분석 및 개선 리포트
## 🔴 심각한 메모리 누수 (즉시 수정 필요)
### 1. **app.vue - watch가 정리되지 않음**
- **위치**: `app/app.vue:131-146`
- **문제**: `onMounted` 내부에서 생성된 `watch``onBeforeUnmount`에서 정리되지 않음
- **영향**: 컴포넌트가 언마운트되어도 watch가 계속 실행되어 메모리 누수 발생
### 2. **useSplideArrow.ts - 이벤트 리스너가 정리되지 않음**
- **위치**: `layers/composables/useSplideArrow.ts:55, 59`
- **문제**: `addEventListener`로 추가된 이벤트 리스너가 제거되지 않음
- **영향**: 컴포넌트가 언마운트되어도 이벤트 리스너가 남아있어 메모리 누수 발생
### 3. **useModalStore.ts - setTimeout이 정리되지 않음**
- **위치**: `layers/stores/useModalStore.ts:125`
- **문제**: `setTimeout`이 사용되지만 컴포넌트 언마운트 시 정리되지 않음
- **영향**: 컴포넌트가 언마운트된 후에도 타이머가 실행되어 메모리 누수 발생
### 4. **useLoadingStore.ts - setTimeout이 정리되지 않음**
- **위치**: `layers/stores/useLoadingStore.ts:38`
- **문제**: `setTimeout`이 사용되지만 정리되지 않음
- **영향**: 스토어가 초기화되어도 타이머가 실행되어 메모리 누수 발생
### 5. **Video.vue - setTimeout이 정리되지 않음**
- **위치**: `layers/components/atoms/Video.vue:34`
- **문제**: `setTimeout`이 사용되지만 컴포넌트 언마운트 시 정리되지 않음
- **영향**: 컴포넌트가 언마운트된 후에도 타이머가 실행되어 메모리 누수 발생
### 6. **GrGallery01/index.vue - setTimeout이 정리되지 않음**
- **위치**: `layers/templates/GrGallery01/index.vue:93`
- **문제**: `setTimeout`이 사용되지만 컴포넌트 언마운트 시 정리되지 않음
- **영향**: 컴포넌트가 언마운트된 후에도 타이머가 실행되어 메모리 누수 발생
### 7. **useGameStart.ts - setTimeout이 정리되지 않음**
- **위치**: `layers/composables/useGameStart.ts:70`
- **문제**: `setTimeout`이 사용되지만 정리되지 않음
- **영향**: 컴포저블이 사용되지 않아도 타이머가 실행되어 메모리 누수 발생
### 8. **Thumbnail.vue - 이벤트 리스너가 정리되지 않음**
- **위치**: `layers/components/blocks/slide/Thumbnail.vue:114`
- **문제**: `addArrowClickListeners`로 추가된 이벤트 리스너가 제거되지 않음
- **영향**: 컴포넌트가 언마운트되어도 이벤트 리스너가 남아있어 메모리 누수 발생
## 🟡 중간 수준 이슈 (개선 권장)
### 9. **amplitude.client.ts - 이벤트 리스너가 정리되지 않음**
- **위치**: `layers/plugins/amplitude.client.ts:34`
- **문제**: `window.addEventListener('pagehide')`가 추가되지만 제거되지 않음
- **영향**: 플러그인은 앱 전체 생명주기 동안 유지되므로 큰 문제는 아니지만, 명시적으로 정리하는 것이 좋음
### 10. **app.vue - removeEventListener 사용 오류**
- **위치**: `app/app.vue:150`
- **문제**: `useEventListener`로 추가한 이벤트 리스너를 `removeEventListener`로 제거하려고 함
- **영향**: `useEventListener`는 자동으로 정리되므로 불필요한 코드 (메모리 누수는 아님)
## 📋 수정 우선순위
1.**즉시 수정** (메모리 누수): #1, #2, #3, #4, #5, #6, #7, #8 - **완료**
2. **단기 개선** (안정성): #9, #10 - 추후 검토
## ✅ 수정 완료 내역
### 수정된 파일 목록
1. `app/app.vue` - watch 정리 추가, removeEventListener 제거
2. `layers/composables/useSplideArrow.ts` - 이벤트 리스너 제거 함수 반환하도록 수정
3. `layers/components/blocks/slide/Thumbnail.vue` - 이벤트 리스너 정리 추가
4. `layers/stores/useModalStore.ts` - setTimeout 정리 추가
5. `layers/stores/useLoadingStore.ts` - setTimeout 정리 추가
6. `layers/components/atoms/Video.vue` - setTimeout 정리 추가
7. `layers/templates/GrGallery01/index.vue` - setTimeout 정리 추가
8. `layers/composables/useGameStart.ts` - setTimeout 정리 추가
### 수정 방법 요약
- **watch 정리**: `watch` 반환값을 저장하고 `onBeforeUnmount`에서 호출
- **setTimeout 정리**: 타이머 ID를 저장하고 `onBeforeUnmount` 또는 함수 재호출 시 `clearTimeout`으로 정리
- **이벤트 리스너 정리**: 이벤트 리스너 제거 함수를 반환하고 `onBeforeUnmount`에서 호출
## 🎯 개선 효과
1. **메모리 누수 방지**: 컴포넌트 언마운트 시 모든 리소스가 정리되어 메모리 누수 방지
2. **성능 향상**: 불필요한 타이머 및 이벤트 리스너 제거로 성능 향상
3. **안정성 향상**: 컴포넌트 생명주기 관리가 명확해져 버그 발생 가능성 감소
4. **코드 품질 향상**: 리소스 정리 패턴이 일관되어 유지보수성 향상
## 📝 추가 권장 사항
1. **자동 정리 유틸 함수**: 공통 패턴을 유틸 함수로 추출하여 재사용성 향상
2. **테스트 강화**: 컴포넌트 언마운트 시 리소스 정리 테스트 추가
3. **ESLint 규칙**: 메모리 누수 방지를 위한 ESLint 규칙 추가 고려
4. **성능 모니터링**: 수정 후 메모리 사용량 모니터링