프로그래밍

[번역] 클라이언트 측의 저장소 살펴보기

원문 : https://bitsofco.de/an-overview-of-client-side-storage/

브라우저 내부에 직접 데이터를 저장하게 되면 많은 장점이 있다. 가장 중요한 장점은 네트워크 없이도 빠르게 “데이터베이스”에 접근할 수 있다는 점이다. 클라이언트 측에 데이터를 저장하는 방식은 현재 다음의 4가지가 있다. (하나가 더 있지만 디프리케이트 되었다)

  1. 쿠키 (Cookies)
  2. 로컬 저장소 (Local Storage)
  3. 세션 저장소 (Session Storage)
  4. IndexedDB
  5. WebSQL (deprecated)

쿠키

쿠키는 문서 내부에 간단한 문자열 데이터를 저장하는 고전적인 방식이다. 일반적으로 쿠키는 서버에서 클라인트로 전송되어 저장되었다가, 이후의 요청을 보낼 때 서버로 다시 전송된다. 쿠키는 계정의 세션을 관리하거나 사용자의 정보를 추적하는 데에 사용될 수 있다.

뿐만 아니라 쿠키는 순수하게 클라이언트 측에서 데이터를 저장하기 위해서도 사용될 수 있다. 이런 이유로 쿠키는 사용자 설정값 등의 데이터를 저장하는 데에 사용되어 왔다.

쿠키를 이용한 기본 CRUD

다음의 문법을 이용해서 쿠키를 생성/읽기/변경/삭제할 수 있다.

// 생성
document.cookie = "user_name=Ire Aderinokun";  
document.cookie = "user_age=25;max-age=31536000;secure";

// 읽기 (전체)
console.log( document.cookie );

// 변경
document.cookie = "user_age=24;max-age=31536000;secure";

// 삭제
document.cookie = "user_name=Ire Aderinokun;expires=Thu, 01 Jan 1970 00:00:01 GMT";

쿠키의 장점

  • 서버와의 커뮤니케이션을 위해 사용될 수 있다.
  • 직접 삭제하지 않아도, 원하는 시기에 자동으로 만기(expire) 되도록 설정할 수 있다.

쿠키의 단점

  • 페이지 부하를 증가시킨다
  • 적은 양의 데이터만 저장할 수 있다
  • 문자열만 저장할 수 있다
  • 잠재적인 보안 이슈가 있다
  • 웹 저장소 API (로컬 저장소와 세션 저장소)가 소개된 이후로는 더이상 클라이언트 측의 저장소로 권장되지 않는다

지원

모든 메이저 브라우저에서 기본적으로 지원된다.

로컬 저장소

로컬 저장소는 웹 저장소 API 중 한가지 형식으로, 브라우저 내부에 키-값 쌍을 저장하기 위한 API이다. 로컬 저장소는 단순한 데이터를 저장하기 위해 쿠키보다 더 직관적이고 안전한 API를 제공함으로써, 쿠키의 문제들을 해결하기 위해 만들어졌다.

기술적으로는 로컬 저장소에 오직 문자열만을 저장할 수 있지만, JSON 데이터를 문자열로 변환하여 저장하면 이를 보완할 수 있다. 이는 로컬 저장소에 쿠키로 할 수 있는 것 보다 조금 더 복잡한 데이터를 저장할 수 있도록 해 준다.

로컬 저장소를 이용한 기본 CRUD

다음의 문법을 이용해서 로컬 저장소에 데이터를 생성/읽기/변경/삭제할 수 있다.

// 생성
const user = { name: 'Ire Aderinokun', age: 25 }  
localStorage.setItem('user', JSON.stringify(user));

// 읽기 (단일)
console.log( JSON.parse(localStorage.getItem('user')) )

// 변경
const updatedUser = { name: 'Ire Aderinokun', age: 24 }  
localStorage.setItem('user', JSON.stringify(updatedUser));

// 삭제
localStorage.removeItem('user');

로컬 저장소의 장점

  • 데이터를 저장하기 위한 (쿠키보다 더) 단순하고 직관적인 인터페이스를 제공한다
  • (쿠키보다 더) 안전한 클라이언트 측의 저장소이다
  • (쿠키보다 더) 많은 데이터를 저장할 수 있다

로컬 저장소의 단점

  • 오직 문자열만 저장할 수 있다

지원

Web Storage API Browser Support

출처 : http://caniuse.com

세션 저장소

세션 저장소는 웹 저장소 API의 두번째 형식이다. 세션 저장소는 데이터가 오직 브라우저의 탭 세션에만 저장된다는 것만 빼고는 로컬 저장소와 정확히 동일하다. 사용자가 다른 페이지로 이동하거나 브라우저를 닫으면, 데이터가 삭제된다.

세션 저장소를 이용한 기본 CRUD

다음의 문법을 이용해서 세션 저장소에 데이터를 생성/읽기/변경/삭제할 수 있다.

// 생성
const user = { name: 'Ire Aderinokun', age: 25 }  
sessionStorage.setItem('user', JSON.stringify(user));

// 읽기 (단일)
console.log( JSON.parse(sessionStorage.getItem('user')) )

// 변경
const updatedUser = { name: 'Ire Aderinokun', age: 24 }  
sessionStorage.setItem('user', JSON.stringify(updatedUser));

// 삭제
sessionStorage.removeItem('user');

세션 저장소의 장점, 단점, 지원

로컬 저장소와 동일하다.

IndexedDB

IndexedDB는 브라우저에 데이터를 저장하기 위한 더욱 더 복잡하고 다방면의 해결책이다. 이는 “많은 양의 구조화된 데이터를 클라이언트 측에 저장하기 위한 저수준의 API” (Mozilla) 이다. 이는 자바스크립트를 기반으로 하는 객체지향 데이터베이스로서, 키를 이용해 인덱스되는 데이터를 쉽게 저장하거나 인출할 수 있게 해 준다.

내 아티클인 프로그레시브 웹 어플리케이션 만들기 에서, IndexedDB를 사용해서 어떻게 오프라인 기반의 어플리케이션을 만들 수 있는 지를 자세하게 다루고 있다.

IndexedDB를 이용한 기본 CRUD

모든 예제에서 나는 IndexedDB의 메소드들을 프라미스 형태로 변경한 버전인 제이크 아치발드의 IndexedDB 프라미스 라이브러리 를 사용하고 있다.

IndexedDB를 사용하는 것은 다른 브라우저 저장 방식을 사용하는 것보다 더 복잡하다. 어떤 데이터를 생성/읽기변경/삭제하기 전에, 먼저 데이터베이스를 열고, 필요한 스토어(데이터베이스의 테이블과 유사한)를 생성해야 한다.

function OpenIDB() {  
    return idb.open('SampleDB', 1, function(upgradeDb) {
        const users = upgradeDb.createObjectStore('users', {
            keyPath: 'name'
        });
    });
}

스토어 내부에 데이터를 생성 (혹은 변경) 하기 위해서는, 다음의 단계들을 따라야 한다.

// 1. 데이터베이스를 연다
OpenIDB().then((db) => {  
    const dbStore = 'users';

    // 2. 데이터베이스 내부에 스토어와 함께 새로운 읽기/쓰기 트랜잭션을 연다
    const transaction = db.transaction(dbStore, 'readwrite');
    const store = transaction.objectStore(dbStore);

    // 3. 스토어에 데이터를 추가한다
    store.put({
        name: 'Ire Aderinokun',
        age: 25
    });

    // 4. 트랜잭션을 완료한다
    return transaction.complete;
});

데이터를 인출하기 위해서는, 다음을 따라야 한다.

// 1. 데이터베이스를 연다
OpenIDB().then((db) => {  
    const dbStore = 'users';

    // 2. 데이터베이스 내부에 스토어와 함께 새로운 읽기 전용 트랜잭션을 연다
    const transaction = db.transaction(dbStore);
    const store = transaction.objectStore(dbStore);

    // 3. 데이터를 반환한다
    return store.get('Ire Aderinokun');
}).then((item) => {
    console.log(item);
})

마지막으로 데이터를 삭제하기 위해서는, 다음을 따라야 한다.

// 1. 데이터베이스를 연다
OpenIDB().then((db) => {  
    const dbStore = 'users';

    // 2. 데이터베이스 내부에 스토어와 함께 새로운 읽기/쓰기 트랜잭션을 연다
    const transaction = db.transaction(dbStore, 'readwrite');
    const store = transaction.objectStore(dbStore);

    // 3. 주어진 키에 대응하는 데이터를 삭제한다
    store.delete('Ire Aderinokun');

    // 4. 트랜잭션을 완료한다
    return transaction.complete;
})

만약 IndexedDB를 어떻게 사용하는지에 대해 더 공부하고 싶다면, 내 아티클를 참고하기 바란다.

IndexedDB의 장점

  • 더 복잡하고 구조적인 데이터를 다룰 수 있다
  • 여러개의 “데이터베이스”, 그리고 각 데이터베이스 내부에 여러개의 “테이블”을 가질 수 있다
  • 더 많은 양의 데이터를 저장할 수 있다
  • 상호작용 시에 더 많은 제어를 할 수 있다

IndexedDB의 단점

  • 웹 저장소 API보다 사용법이 더 복잡하다

지원

IndexedDB Browser Support

출처 : http://caniuse.com

WebSQL

WebSQL은 클라이언트 측의 관계형 데이터베이스를 위한 API로, SQLite와 유사하다. 2010년 이후로 W3C 웹 어플리케이션 워킹 그룹은 이 스펙에 대한 작업을 중단했다. WebSQL은 이제 더이상 HTML 스펙이 아니므로, 사용하지 말아야 한다.

비교

특징 쿠키 로컬 저장소 세션 저장소 IndexedDB
저장소 제한 ~4KB ~5MB ~5MB 하드디스크의 절반까지
영구적 저장? Yes Yes No Yes
데이터 저장 형식 문자열 문자열 문자열 모든 구조적 데이터
인덱스화 No No No Yes