공식문서

Introduction to caching

Data? _cachedData;

Future<Data> get data async {
    // Step 1: Check whether your cache already contains the desired data
    if (_cachedData == null) {
        // Step 2: Load the data if the cache was empty
        _cachedData = await _readData();
    }
    // Step 3: Return the value in the cache
    return _cachedData!;
}

caching하는 방법을 pseudocode로 작성하였다.
여러 방법이 있는데, 미리 데이터를 캐시에 저장하여 웜업하는 방법 등이 있다.

Common caching terminology

  • Cache hit
    원하는 정보가 이미 저장되어 있고, 데이터 검증이 필요 없는 경우 발생

  • Cache miss
    원하는 정보가 없고, 데이터를 호출해야 하는 경우 발생

Risks of caching data

실제 데이터가 갱신되면 stale cache 상태가 된다.
이 경우, 새롭게 데이터를 캐시에 저장해야 한다.

모든 캐싱 전략은 stale data를 다루는 부분에서 리스크를 가진다.
너무 빈번하게 캐시 데이터를 검증하면 데이터 호출에 오랜 시간이 걸린다.
즉, 대부분의 앱은 별도의 검증 없이 캐시의 데이터가 유효하다고 믿고 진행시킨다.

대부분 캐시 데이터의 유효 시간은 정해져 있다.
해당 시간이 지나면 cache miss가 발생하고, 새로운 데이터를 호출한다.

Caching data in local memory

class UserRepository {
  UserRepository(this.api);
  
  final Api api;
  final Map<int, User?> _userCache = {}; // in-memory cache

  Future<User?> loadUser(int id) async {
    if (!_userCache.containsKey(id)) {
      final response = await api.get(id);
      if (response.statusCode == 200) {
        _userCache[id] = User.fromJson(response.body);
      } else {
        _userCache[id] = null;
      }
    }
    return _userCache[id];
  }
}

가장 간단하고 성능이 뛰어난 방법은 in-memory 캐싱 방법이다.
이 방법은 캐시가 시스템 메모리에 저장되기 때문에 세션이 종료되면 캐시도 사라진다.
물론 부수 효과로 자동으로 stale cache가 사라진다는 점도 있다.

위와 같은 repository pattern은 3가지 장점을 가진다.

  • dependency injection
  • loose coupling
  • separation of concerns

하지만 in-memory 캐싱은 앱을 다시 설치하면 데이터를 다시 로드해야 하기 때문에 UX적으로 좋지 않다.

Persistent caches

캐시를 유지하려면 데이터를 디바이스의 하드 드라이브에 저장해야 한다.

Caching data with shared_preferences

shared_preferenceskey-value storage로 구성된 플러터 플러그인이다.
작은 사이즈의 데이터 저장에 유용하며 대부분의 캐싱 전략에도 부합한다.

Caching data with the file system

만약 low-throughput 시나리오를 넘어서는 경우, shared_preference를 사용하지 말자.
디바이스의 파일 시스템에 저장하는 방법을 고려해보자.

참고로 low-throughput 시나리오는 데이터의 읽기/쓰기 빈도가 낮고, 소량의 데이터를 저장하는 경우를 말한다.

Caching data with an on-device database

최종 방법은 적절한 DB에 데이터를 읽고 쓰는 것이다.
관계형/비관계형 DB가 존재하고, 모두 데이터가 큰 경우에 엄청난 성능 향상을 보여준다.

Caching images

이미지를 캐싱하고 싶으면 아래의 패키지를 사용해보자.

State restoration

네비게이션 스택, 스크롤 위치, 입력 중이던 폼 데이터와 같이 유저 관련 데이터를 저장하고 싶을 때가 있다.
이러한 패턴을 state restoration이라 부르고, 플러터에서 기본적으로 지원한다.

플러터는 element tree에서 데이터를 가져와 플러터 엔진과 동기화한다.
그 후, 해당 데이터를 플랫폼별 저장소에 캐싱하여 다음 세션에서도 유지할 수 있도록 한다.

profile
Software Engineer

0개의 댓글