[HTML5]ダウンロードデータのキャッシュとしてWeb Storageを使う
囲碁定石トレーニングを、「ダウンロードした定石データをWeb Storageに格納する」ように修正した。
目次
1. localStorageかsessionStorageか
2. Web Storageを使用可能かチェック
3. Web Storageにデータが存在するかチェック
4. Web Storageにデータを登録する
1. localStorageかsessionStorageか
Web StorageにはlocalStorageとsessionStorageがある。
有効期限が無いlocalStorageの方が、無駄なダウンロードをより削減することができる。
ただし、定石データの変更があった場合にデータの同期を取る必要がある。
今はそこまでしてダウンロードを減らす必要が無いので、タブを開いているときだけ有効なsessionStorageを使うことにした。
Web Storageを使用できない環境では、今まで通りキャッシュ用オブジェクトに格納するようにした。
2. Web Storageを使用可能かチェック
コードは以下のようになった。
cookieをブロックしていたりすると例外が発生するので、try catchで例外対応をしている。(詳細は[HTML5]Web Storageについて調べるを参照)
例外を発生させるためにダミーデータをsetItemしている。
JSONオブジェクトは、オブジェクト⇔文字列 の変換に使用するためチェックしている。
3. Web Storageにデータが存在するかチェック
コードは以下のようになった。
4. Web Storageにデータを登録する
コードは以下のようになった。
setItemで例外が発生した場合は、キャッシュを登録せずにフラグをオフにする。次にダウンロードしたときに、キャッシュオブジェクトに登録される。
キャッシュオブジェクトでは上限を設定しているが、今の定石データは合計25KB以下なのでsessionStorageでは上限チェックをしていない。
以上。難しいことは何も無かった。
各ブラウザでcookieをブロックしたり許可したりしてテストするのが面倒だったぐらい。
目次
1. localStorageかsessionStorageか
2. Web Storageを使用可能かチェック
3. Web Storageにデータが存在するかチェック
4. Web Storageにデータを登録する
1. localStorageかsessionStorageか
Web StorageにはlocalStorageとsessionStorageがある。
有効期限が無いlocalStorageの方が、無駄なダウンロードをより削減することができる。
ただし、定石データの変更があった場合にデータの同期を取る必要がある。
今はそこまでしてダウンロードを減らす必要が無いので、タブを開いているときだけ有効なsessionStorageを使うことにした。
Web Storageを使用できない環境では、今まで通りキャッシュ用オブジェクトに格納するようにした。
2. Web Storageを使用可能かチェック
コードは以下のようになった。
mijoseki.act.isStorage = false;
try {
if (typeof sessionStorage != 'undefined' && typeof JSON != 'undefined') {
sessionStorage.setItem('test000', 'check if storage is available');
mijoseki.act.isStorage = true;
}
} catch(e) {
mijoseki.act.isStorage = false;
}
Web Storageが使用可能ならmijoseki.act.isStorageフラグをオンにするだけの処理。try {
if (typeof sessionStorage != 'undefined' && typeof JSON != 'undefined') {
sessionStorage.setItem('test000', 'check if storage is available');
mijoseki.act.isStorage = true;
}
} catch(e) {
mijoseki.act.isStorage = false;
}
cookieをブロックしていたりすると例外が発生するので、try catchで例外対応をしている。(詳細は[HTML5]Web Storageについて調べるを参照)
例外を発生させるためにダミーデータをsetItemしている。
JSONオブジェクトは、オブジェクト⇔文字列 の変換に使用するためチェックしている。
3. Web Storageにデータが存在するかチェック
コードは以下のようになった。
/**
* 問題データキャッシュチェック
* @param {string} probkey 問題のkey値
* @return {Object} this.setprob() でセットする問題データ。
* 該当するキャッシュが無い場合はnull。
*/
mijoseki.Action_.prototype.chkpCache = function(probkey) {
var pdata = null;
if (this.isStorage) {
pdata = sessionStorage.getItem(probkey);
if (pdata) {
pdata = JSON.parse(pdata);
}
} else{
// sessionStorageが使用できない環境での処理
if (this.pdatacache[probkey]) {
pdata = this.pdatacache[probkey];
}
}
return pdata;
};
キー値に該当するデータがあったら、JSON.parse()でオブジェクトに変換してreturnするだけ。* 問題データキャッシュチェック
* @param {string} probkey 問題のkey値
* @return {Object} this.setprob() でセットする問題データ。
* 該当するキャッシュが無い場合はnull。
*/
mijoseki.Action_.prototype.chkpCache = function(probkey) {
var pdata = null;
if (this.isStorage) {
pdata = sessionStorage.getItem(probkey);
if (pdata) {
pdata = JSON.parse(pdata);
}
} else{
// sessionStorageが使用できない環境での処理
if (this.pdatacache[probkey]) {
pdata = this.pdatacache[probkey];
}
}
return pdata;
};
4. Web Storageにデータを登録する
コードは以下のようになった。
/**
* 問題データキャッシュセット
* @param {string} probkey 問題のkey値
* @param {Object} pdata セットする問題データ
*/
mijoseki.Action_.prototype.setpCache = function(probkey, pdata) {
if (this.isStorage) {
var setdata = JSON.stringify(pdata);
try {
sessionStorage.setItem(probkey, setdata);
} catch(e) {
// 保存容量オーバーなどでStorage使用不可の場合
mijoseki.act.isStorage = false;
}
} else{
// sessionStorageが使用できない環境での処理
if (!this.pdatacache[probkey]) {
if (this.pdatacname.length >= mijoseki.con.num.climit) {
// キャッシュ数が上限のため、古いキャッシュを削除
var delval = this.pdatacname.shift();
delete this.pdatacache[delval];
}
this.pdatacname.push(probkey);
}
// pdataをshallow copyしてキャッシュに格納
var pdatacp = {};
for (var prop in pdata) {
pdatacp[prop] = pdata[prop];
}
this.pdatacache[probkey] = pdatacp;
}
};
Web Storageには(今現在では)オブジェクトを登録できないので、JSON.stringify()で文字列に変換している。* 問題データキャッシュセット
* @param {string} probkey 問題のkey値
* @param {Object} pdata セットする問題データ
*/
mijoseki.Action_.prototype.setpCache = function(probkey, pdata) {
if (this.isStorage) {
var setdata = JSON.stringify(pdata);
try {
sessionStorage.setItem(probkey, setdata);
} catch(e) {
// 保存容量オーバーなどでStorage使用不可の場合
mijoseki.act.isStorage = false;
}
} else{
// sessionStorageが使用できない環境での処理
if (!this.pdatacache[probkey]) {
if (this.pdatacname.length >= mijoseki.con.num.climit) {
// キャッシュ数が上限のため、古いキャッシュを削除
var delval = this.pdatacname.shift();
delete this.pdatacache[delval];
}
this.pdatacname.push(probkey);
}
// pdataをshallow copyしてキャッシュに格納
var pdatacp = {};
for (var prop in pdata) {
pdatacp[prop] = pdata[prop];
}
this.pdatacache[probkey] = pdatacp;
}
};
setItemで例外が発生した場合は、キャッシュを登録せずにフラグをオフにする。次にダウンロードしたときに、キャッシュオブジェクトに登録される。
キャッシュオブジェクトでは上限を設定しているが、今の定石データは合計25KB以下なのでsessionStorageでは上限チェックをしていない。
以上。難しいことは何も無かった。
各ブラウザでcookieをブロックしたり許可したりしてテストするのが面倒だったぐらい。
スポンサーサイト