docs: 프로젝트 문서화 및 개발 가이드 추가
- 데이터베이스 스키마 및 변경 로그 문서화 - 신규 페이지 개발 가이드 작성 - 모듈 아키텍처 설계 문서 추가 - 성능 최적화 전략 문서화 - 리팩토링 계획 및 진행 상황 정리 Documentation: - DATABASE_SCHEMA.md: 전체 DB 스키마 구조 - DB_CHANGE_LOG.md: 마이그레이션 변경 이력 - DEVELOPMENT_GUIDE.md: 신규 기능 개발 표준 - MODULE_ARCHITECTURE.md: 프론트엔드 모듈 구조 - PERFORMANCE_OPTIMIZATION.md: 성능 최적화 가이드 - REFACTORING_PLAN.md: 리팩토링 진행 상황 Test Files: - app.html, app.js: SPA 테스트 파일 - test_api.html: API 테스트 페이지
This commit is contained in:
255
PERFORMANCE_OPTIMIZATION.md
Normal file
255
PERFORMANCE_OPTIMIZATION.md
Normal file
@@ -0,0 +1,255 @@
|
||||
# M-Project 성능 최적화 가이드
|
||||
|
||||
## 개요
|
||||
M-Project의 성능 최적화 기능들과 사용 방법을 설명합니다.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 구현된 최적화 기능
|
||||
|
||||
### 1. 페이지 프리로딩 시스템
|
||||
**파일**: `frontend/static/js/core/page-preloader.js`
|
||||
|
||||
#### 기능
|
||||
- **우선순위 기반 프리로딩**: 사용자 권한에 따른 접근 가능한 페이지를 우선순위별로 프리로드
|
||||
- **호버 프리로딩**: 링크에 마우스를 올렸을 때 해당 페이지를 미리 로드
|
||||
- **리소스 프리로딩**: HTML과 함께 CSS, JS 파일도 함께 프리로드
|
||||
- **네트워크 감지**: 느린 연결에서는 프리로딩을 중단하여 사용자 경험 보호
|
||||
|
||||
#### 사용법
|
||||
```javascript
|
||||
// 자동 초기화 (공통 헤더에서 자동 실행)
|
||||
window.pagePreloader.init();
|
||||
|
||||
// 수동 프리로드
|
||||
await window.pagePreloader.preloadPage({
|
||||
id: 'issues_view',
|
||||
url: '/issue-view.html',
|
||||
priority: 1
|
||||
});
|
||||
|
||||
// 캐시 정리
|
||||
window.pagePreloader.clearCache();
|
||||
```
|
||||
|
||||
#### 우선순위 설정
|
||||
1. **Priority 1**: 부적합 등록, 부적합 조회 (기본 접근 페이지)
|
||||
2. **Priority 2**: 부적합 관리, 일일 공수
|
||||
3. **Priority 3**: 프로젝트 관리, 보고서
|
||||
4. **Priority 4**: 사용자 관리 (관리자 전용)
|
||||
|
||||
### 2. 서비스 워커 캐싱
|
||||
**파일**: `frontend/sw.js`
|
||||
|
||||
#### 캐시 전략
|
||||
- **Network First**: API 호출 (`/api/`, `/auth/`)
|
||||
- **Cache First**: 정적 리소스 (CSS, JS, 이미지, 폰트)
|
||||
- **Stale While Revalidate**: HTML 페이지
|
||||
|
||||
#### 캐시 종류
|
||||
- **Static Cache**: 변경되지 않는 리소스
|
||||
- **Dynamic Cache**: API 응답 및 동적 콘텐츠
|
||||
- **CDN Cache**: 외부 라이브러리 (Tailwind, Font Awesome)
|
||||
|
||||
#### 오프라인 지원
|
||||
- HTML 페이지: 기본 페이지로 폴백
|
||||
- 이미지: SVG 플레이스홀더 제공
|
||||
- API: 캐시된 응답 반환
|
||||
|
||||
### 3. 키보드 단축키 시스템
|
||||
**파일**: `frontend/static/js/core/keyboard-shortcuts.js`
|
||||
|
||||
#### 주요 단축키
|
||||
| 단축키 | 기능 | 설명 |
|
||||
|--------|------|------|
|
||||
| `?` | 도움말 표시 | 모든 단축키 목록 보기 |
|
||||
| `Esc` | 모달/메뉴 닫기 | 열린 모달이나 드롭다운 닫기 |
|
||||
| `g h` | 홈 이동 | 부적합 등록 페이지로 이동 |
|
||||
| `g v` | 조회 이동 | 부적합 조회 페이지로 이동 |
|
||||
| `g d` | 일일 공수 | 일일 공수 페이지로 이동 |
|
||||
| `g p` | 프로젝트 관리 | 프로젝트 관리 페이지로 이동 |
|
||||
| `g a` | 관리자 | 관리자 페이지로 이동 |
|
||||
| `n` | 새 항목 | 새 항목 생성 버튼 클릭 |
|
||||
| `s` | 저장 | 저장 버튼 클릭 |
|
||||
| `r` | 새로고침 | 페이지 새로고침 |
|
||||
| `f` | 검색 포커스 | 검색 필드에 포커스 |
|
||||
|
||||
#### 권한 기반 단축키
|
||||
- **일반 사용자**: 기본 네비게이션 및 액션 단축키
|
||||
- **관리자**: 모든 단축키 + 관리자 전용 단축키
|
||||
- **입력 필드**: 제한된 단축키만 작동 (Esc, Ctrl+S 등)
|
||||
|
||||
### 4. 공통 헤더 시스템
|
||||
**파일**: `frontend/static/js/components/common-header.js`
|
||||
|
||||
#### 성능 최적화
|
||||
- **권한 기반 메뉴**: 접근 불가능한 메뉴는 렌더링하지 않음
|
||||
- **지연 로딩**: 권한 시스템 로드 후 헤더 렌더링
|
||||
- **이벤트 위임**: 효율적인 이벤트 처리
|
||||
- **부드러운 전환**: 150ms 딜레이로 자연스러운 페이지 이동
|
||||
|
||||
---
|
||||
|
||||
## 📊 성능 측정 및 모니터링
|
||||
|
||||
### 1. 브라우저 개발자 도구 활용
|
||||
```javascript
|
||||
// 페이지 로드 시간 측정
|
||||
console.time('페이지 로드');
|
||||
window.addEventListener('load', () => {
|
||||
console.timeEnd('페이지 로드');
|
||||
});
|
||||
|
||||
// 프리로드 상태 확인
|
||||
console.log('프리로드된 페이지:', window.pagePreloader.preloadedPages);
|
||||
console.log('리소스 캐시:', window.pagePreloader.resourceCache);
|
||||
```
|
||||
|
||||
### 2. 서비스 워커 상태 확인
|
||||
```javascript
|
||||
// 캐시 상태 조회
|
||||
navigator.serviceWorker.controller?.postMessage({
|
||||
type: 'GET_CACHE_STATUS'
|
||||
});
|
||||
|
||||
// 캐시 정리
|
||||
navigator.serviceWorker.controller?.postMessage({
|
||||
type: 'CLEAR_CACHE'
|
||||
});
|
||||
```
|
||||
|
||||
### 3. 네트워크 성능 모니터링
|
||||
```javascript
|
||||
// 연결 상태 확인
|
||||
if ('connection' in navigator) {
|
||||
const connection = navigator.connection;
|
||||
console.log('연결 타입:', connection.effectiveType);
|
||||
console.log('데이터 절약 모드:', connection.saveData);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚡ 성능 최적화 팁
|
||||
|
||||
### 1. 프리로딩 최적화
|
||||
```javascript
|
||||
// 중요한 페이지만 프리로드
|
||||
const priorityPages = ['issues_create', 'issues_view'];
|
||||
|
||||
// 네트워크 상태에 따른 조건부 프리로딩
|
||||
if (!window.pagePreloader.isSlowConnection()) {
|
||||
window.pagePreloader.startPreloading(priorityPages);
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 캐시 전략 조정
|
||||
```javascript
|
||||
// 자주 변경되는 API는 네트워크 우선
|
||||
const networkFirstPatterns = [
|
||||
/\/api\/issues/,
|
||||
/\/api\/users/
|
||||
];
|
||||
|
||||
// 정적 리소스는 캐시 우선
|
||||
const cacheFirstPatterns = [
|
||||
/\.css$/,
|
||||
/\.js$/,
|
||||
/\.png$/
|
||||
];
|
||||
```
|
||||
|
||||
### 3. 메모리 관리
|
||||
```javascript
|
||||
// 페이지 이동 시 정리
|
||||
window.addEventListener('beforeunload', () => {
|
||||
// 이벤트 리스너 정리
|
||||
if (window.pageManager) {
|
||||
window.pageManager.cleanup();
|
||||
}
|
||||
|
||||
// 캐시 정리 (필요시)
|
||||
if (performance.memory?.usedJSHeapSize > 50 * 1024 * 1024) {
|
||||
window.pagePreloader.clearCache();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 4. 이미지 최적화
|
||||
```javascript
|
||||
// 지연 로딩
|
||||
const images = document.querySelectorAll('img[data-src]');
|
||||
const imageObserver = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
const img = entry.target;
|
||||
img.src = img.dataset.src;
|
||||
imageObserver.unobserve(img);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
images.forEach(img => imageObserver.observe(img));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 디버깅 및 문제 해결
|
||||
|
||||
### 1. 프리로더 디버깅
|
||||
```javascript
|
||||
// 프리로드 상태 확인
|
||||
console.log('프리로드 진행 중:', window.pagePreloader.isPreloading);
|
||||
console.log('프리로드된 페이지 수:', window.pagePreloader.preloadedPages.size);
|
||||
|
||||
// 프리로드 실패 원인 확인
|
||||
window.pagePreloader.addEventListener('error', (error) => {
|
||||
console.error('프리로드 실패:', error);
|
||||
});
|
||||
```
|
||||
|
||||
### 2. 서비스 워커 디버깅
|
||||
```javascript
|
||||
// 서비스 워커 상태 확인
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
console.log('서비스 워커 상태:', registration.active?.state);
|
||||
});
|
||||
|
||||
// 캐시 내용 확인
|
||||
caches.keys().then(cacheNames => {
|
||||
console.log('사용 가능한 캐시:', cacheNames);
|
||||
});
|
||||
```
|
||||
|
||||
### 3. 성능 문제 해결
|
||||
- **느린 페이지 로드**: 프리로딩 우선순위 조정
|
||||
- **메모리 누수**: 이벤트 리스너 정리 확인
|
||||
- **캐시 문제**: 서비스 워커 재등록
|
||||
- **키보드 단축키 충돌**: 입력 필드 예외 처리 확인
|
||||
|
||||
---
|
||||
|
||||
## 📈 성능 지표 목표
|
||||
|
||||
### 1. 로딩 성능
|
||||
- **첫 페이지 로드**: < 3초
|
||||
- **후속 페이지 로드**: < 1초 (프리로드된 경우)
|
||||
- **API 응답**: < 1초
|
||||
|
||||
### 2. 사용자 경험
|
||||
- **페이지 전환**: < 150ms
|
||||
- **키보드 단축키 반응**: < 100ms
|
||||
- **검색 결과**: < 500ms
|
||||
|
||||
### 3. 리소스 사용량
|
||||
- **메모리 사용량**: < 100MB
|
||||
- **캐시 크기**: < 50MB
|
||||
- **네트워크 요청**: 최소화
|
||||
|
||||
---
|
||||
|
||||
**작성일**: 2025-10-25
|
||||
**버전**: 1.0
|
||||
**작성자**: AI Assistant
|
||||
|
||||
> 성능 최적화는 지속적인 모니터링과 개선이 필요합니다.
|
||||
Reference in New Issue
Block a user