'localstorage'에 해당되는 글 1건

  1. 2018.05.10 [자바스크립트] JSON 객체를 브라우저에 캐시 하는 방법
개발팁2018. 5. 10. 17:38

닷넷에서 데이터를 캐시하기위해서는


1. System.Web 의 Cache 를 이용하거나,

2. System.Runtime 의 ObjectCache 를 이용하여, 캐시 데이터를 저장할 수 있다.


Cache 를 생성할때는, 만료시간(Expiration Time)과 만료방식을 2가지로 설정해줄 수 있다.


1. Absolute Expiration

2. Sliding Expiration


Absolute Expiration 은 지정된 시간이 되면, 무조건 캐시 데이터가 만료되고,

Sliding Expiration 은 지정된 시간이 되면, 무조건 만료되는것은 동일하지만, 캐시 데이터를 읽기(Get)를 하게 되면, 만료시간이 다시 늘어나는 방식이다. (로그인 세션을 생각하면 이해가 쉬울것이다.)



클라이언트(웹브라우저)에 데이터를 캐시하기 위해서 쿠키(Cookie) 를 사용할 수도 있지만, 이는 굉장히 비효율적이다.

서버로 Request 를 할때마다 불필요한 트래픽이 발생하며, 저장용량도 4K 정도로 매우 작다.


그래서, 브라우저 내에서 필요한 캐시를 하기 위해, LocalStorage 또는 SessionStorage 를 사용할 것이다.


LocalStorage 은 디스크내에 저장이 되며, 브라우저에 따라 5M ~ 10M 정도의 저장공간을 제공하고, 브라우저가 종료되도 데이터는 유지가 된다.

SessionStorage 는 메모리 내에 존재하며, 브라우저 세션이 종료 (브라우저가 종료) 되면, 데이터도 삭제된다.


LocalStorage / SessionStorage 는 별도의 Expiration Time 기능을 제공하지 않고,

getItem / setItem / removeItem 등의 함수만 제공이 된다.


이를 활용하여, Expiration Time 과 Expiration 방법도 함께 적용해 볼것이다.



// -----------------------------------------------------------------------------------------------------

// Cache Base Object

// Author : bemeal2@naver.com

// do not remove any comments

// -----------------------------------------------------------------------------------------------------

window.cache = {

    get: function (key, isSlidingExpiration, expirationHour) {

        let jsonString = window.sessionStorage && window.sessionStorage.getItem && window.sessionStorage.getItem(key);

        if (jsonString) {

            let cacheData = JSON.parse(jsonString);

            let expirationDate = new Date(cacheData.expirationDate);

            if (expirationDate > new Date()) { // 만료시간 체크 : 지났으면 삭제

let cacheDataObject = JSON.parse(cacheData.value);

if(isSlidingExpiration) // Sliding Expiration 이라면

{

this.set(key, cacheDataObject, expirationHour); // 만료시간을 연장하기 위해, Cache Data 를 재설정한다.

}

                return cacheDataObject;

            } else {

                this.remove(key);

            }

        }

        return null;

    },

    set: function(key, value, expirationHour) {

        let expirationDate = new Date(new Date().getTime() + (60 * 60000 * expirationHour))

        let cacheData = {

            value: JSON.stringify(value),

            expirationDate: expirationDate.toISOString()

        }

        window.sessionStorage && window.sessionStorage.setItem && window.sessionStorage.setItem(key, JSON.stringify(cacheData))

    },

    remove: function (key) {

        window.sessionStorage && window.sessionStorage.removeItem && window.sessionStorage.removeItem(key);

    }

}; 



우선 Base 객체를 하나 생성한다.

이름은 window.cache 이며, get / set / remove 3개의 함수만으로 이루어져 있다.


window.sessionStorage 를 사용하고 있지만, localStorage 를 사용하고자 한다면, 


window.sessionStorage => window.localStorage 로 바꾸기만 하면 된다.



원리는 간단하다.


1. 저장할때는 sessionStorage 에 JSON 객체를 stringify 로 문자열 형태로 바꿔서 저장하고,

    읽어올때는 JSON.parse 로 해서, 다시 객체 형태로 읽어온다.

2. 이때, 만료시간을 지정하기 위해, cacheData 라는 json 객체로 감싸서, value / expirationDate 로 저장하고 있다.

3. 또한, 가져오기(get) 할때, sliding 캐쉬일경우에는 만료시간을 늘려주기 위해 다시  set 함수를 호출하고 있다.



이 window.cache 객체 그대로도 사용할 수 있지만, 매번 함수안에 파라미터를 넣어줘야 한다. 이를 상속하여, 단순화 시켜 보자.


// -----------------------------------------------------------------------------------------------------

// Object Cache Data

// Author : bemeal2@naver.com

// do not remove any comments

// -----------------------------------------------------------------------------------------------------

window.cache.data = Object.create(window.cache, {

    cacheData: { value: "data", enumerable: false, writable: false },

isSlidingExpiration: { value: false, enumerable: false, writable: true }, // default : Absolute Expiration

    expirationHour: { value: 1, enumerable: false, writable: true }    // default expiration : 1 hour

});


window.cache.data.setObject = function (data) {

    let self = this;

    self.set(self.cacheData, data, self.expirationHour); // expiration hour : default 1 hour

}


window.cache.data.getObject = function () {

    let self = this;

    let data = self.get(self.cacheData, self.isSlidingExpiration, self.expirationHour);


    return data;

}


window.cache.data.removeObject = function () {

    let self = this;

    self.remove(self.cacheData);

}



setObject / getObject  / removeObject  3개의 함수를 가지는 window.cache.data 객체를 만들었다.


옵션으로 cacheData , isSlidingExpiration , expirationHour 값을 가지고 있다.

실제 저장할 데이터에 따라 이 3가지 값을 변경하면서 저장하면된다.


마지막으로, 이 객체를 상속하여, 실제 사용하는 객체를 생성할 것이다.



// Sliding Expiration 캐시 예제

window.cache.data.locale_data = Object.create(window.cache.data, {

    cacheData: { value: "locale_data", enumerable: false, writable: false },

    isSlidingExpiration: { value: true, enumerable: false, writable: true }, // sliding expiration

    expirationHour: { value: 1, enumerable: false, writable: true }    // expiration timeout : 1 hour

});


// Absolute Expiration 캐시 예제

window.cache.data.server_config = Object.create(window.cache.data, {

    cacheData: { value: "server_config", enumerable: false, writable: false },

    isSlidingExpiration: { value: false, enumerable: false, writable: true }, // absolute expiration

    expirationHour: { value: 0.5, enumerable: false, writable: true }    // expiration timeout : 30 minute

});



위에서는 window.cache.data.locale_data 와 window.cache.data.server_config 를 생성했지만,

위의 cacheData string 값을 변경하여, 무한하게 생성해서 사용하면 된다.




사용예1)

window.cache.data.locale_data.setObject( master_data.masterData );

window.cache.data.locale_data.getObject();


사용예2)

window.cache.data.server_config.setObject( master_data.server_config_list_array );

window.cache.data.server_config.getObject();






실제로, locale_data 는 getObject() 를 할때마다, expiratioDate 값이 변하는것을 확인할 수 있다.



주의 : 위의 방식은, 만료시간이 되었다고 해서, 실제로 메모리에서 캐시 데이터가 삭제되는것이 아니라, get 함수를 호출할때, 만료시간을 체크하여, 캐시 데이터를 삭제하는 방식이다.

만약 get / set 등을 하지 않는 시간에도, 만료된 캐시를 삭제하고 싶다면, Observer 객체를 만들어서, 주기적으로 만료시간을 체크하여야 할것이다.



Posted by 헝개