카테고리 없음

캐시 vs 로컬스토리지 vs 세션스토리지

sesam 2025. 7. 31. 11:49
728x90

각 저장 방식의 특징

1. 캐시 (Memory Cache)

// 현재 구현한 방식
public usageDataCache: { [date: string]: DailyUsageData } = {};
  • 가장 빠른 접근 속도 (메모리에서 직접 읽기)
  • 페이지 새로고침 시 자동으로 초기화되어 최신 데이터 보장
  • 구현이 간단하고 직관적
  • 단점:
  • 페이지를 벗어나면 데이터 손실
  • 브라우저 메모리 사용량 증가

2. 로컬스토리지 (LocalStorage)

// 로컬스토리지 사용 예시
public saveToLocalStorage() {
    localStorage.setItem('usageDataCache', JSON.stringify(this.usageDataCache));
}

public loadFromLocalStorage() {
    const cached = localStorage.getItem('usageDataCache');
    if (cached) {
        this.usageDataCache = JSON.parse(cached);
    }
}
 
 
  • 장점:
  • 브라우저를 닫아도 데이터 유지
  • 용량이 큼 (5-10MB)
  • 단점:
  • 문자열로 변환/파싱 필요 (성능 저하)
  • 오래된 데이터가 남아있을 수 있음
  • 보안상 민감한 데이터 노출 위험

3. 세션스토리지 (SessionStorage)

// 세션스토리지 사용 예시
public saveToSessionStorage() {
    sessionStorage.setItem('usageDataCache', JSON.stringify(this.usageDataCache));
}
  • 장점:
  • 탭을 닫을 때까지 데이터 유지
  • 탭별로 독립적인 저장소
  • 단점:
  • 탭을 닫으면 데이터 손실
  • 로컬스토리지와 동일한 성능 이슈

왜 캐시를 선택했는가?

1. 데이터 특성상 적합

// 사용량 데이터는 실시간성이 중요
public cacheExpiryTime: number = 5 * 60 * 1000; // 5분 만료
  • 사용량 데이터는 실시간성이 중요
  • 5분만 지나도 데이터가 오래될 수 있음
  • 페이지 새로고침 시 최신 데이터를 보여주는 것이 더 중요

2. 성능 최적화

// 메모리에서 직접 접근 - 매우 빠름
const cachedData = this.usageDataCache[selectedDateString];
if (cachedData) {
    // 즉시 사용 가능
    this.updateUsageDataForSelectedDate();
}
  • 날짜 선택 시 즉시 반응 필요
  • JSON 파싱/직렬화 오버헤드 없음
  • 사용자 경험 향상

3. 구현 복잡도

  • 복잡한 저장/로드 로직 불필요
  • 에러 처리 단순화
  • 디버깅 용이

 

다른 방식으로 구현한다면?

하이브리드 방식 (추천)

export default class ChatbotDashboardStore {
    // 메모리 캐시 (빠른 접근용)
    public usageDataCache: { [date: string]: DailyUsageData } = {};
    
    // 로컬스토리지 백업 (지속성용)
    public saveToLocalStorage() {
        const dataToSave = {
            cache: this.usageDataCache,
            timestamp: Date.now(),
            expiryTime: this.cacheExpiryTime
        };
        localStorage.setItem('usageDataCache', JSON.stringify(dataToSave));
    }
    
    public loadFromLocalStorage() {
        const saved = localStorage.getItem('usageDataCache');
        if (saved) {
            const data = JSON.parse(saved);
            const isExpired = Date.now() - data.timestamp > data.expiryTime;
            
            if (!isExpired) {
                this.usageDataCache = data.cache;
                this.isCacheLoaded = true;
                this.lastCacheUpdate = data.timestamp;
            }
        }
    }
    
    public *init() {
        // 먼저 로컬스토리지에서 로드 시도
        this.loadFromLocalStorage();
        
        // 캐시가 없거나 만료되었으면 새로 로드
        if (!this.isCacheLoaded || this.isCacheExpired()) {
            yield this.loadWeeklyUsageData();
            this.saveToLocalStorage(); // 백업 저장
        }
        
        yield this.loadUsageDataForDate();
        yield this.loadUsageDataForToday();
    }
}

 

 

IndexedDB 방식 (대용량 데이터용)

// IndexedDB 사용 예시 (복잡하지만 강력함)
public async saveToIndexedDB() {
    const db = await this.openDB();
    const tx = db.transaction(['usageData'], 'readwrite');
    const store = tx.objectStore('usageData');
    
    for (const [date, data] of Object.entries(this.usageDataCache)) {
        await store.put({ date, data, timestamp: Date.now() });
    }
}

 

 

 

세션스토리지 vs 로컬스토리지 vs 메모리 캐시 비교

 

구분 메모리 캐시 세션스토리지 로컬스토리지

구분 메모리 캐시 세션스토리지 로컬스토리지
저장 위치 메모리 브라우저 저장소 브라우저 저장소
지속성 페이지 새로고침 시 손실 탭 닫을 때까지 유지 브라우저 닫아도 유지
용량 메모리 한계 5-10MB 5-10MB
접근 속도 매우 빠름 빠름 빠름
탭 간 공유 불가능 불가능 가능
데이터 형식 객체 그대로 문자열 (JSON) 문자열 (JSON)

 

결론

현재 구현한 메모리 캐시가 선택된 이유:

  1. 사용 패턴: 사용자가 날짜를 자주 바꾸며 즉시 반응 필요
  2. 데이터 특성: 실시간성이 중요한 사용량 데이터
  3. 구현 단순성: 복잡한 저장/로드 로직 불필요
  4. 성능: 가장 빠른 접근 속도

만약 페이지 새로고침 후에도 데이터를 유지하고 싶다면, 위의 하이브리드 방식을 추천합니다. 이렇게 하면 메모리 캐시의 빠른 성능과 로컬스토리지의 지속성을 모두 얻을 수 있습니다.

 

현재 구현에서는 메모리 캐시가 가장 적합하지만, 만약 다중 탭 지원이나 페이지 새로고침 후 상태 복원이 필요하다면 세션스토리지가 좋은 선택이 될 수 있습니다.

728x90