H 5の「オフラインアプリケーション」
H 5の「オフラインメモリ」
「オフラインストレージ」:名前の通り、有線環境でデータ(静的リソース、動的リソースを含む)をキャッシュし、オフライン環境でもアプリケーションを正常に使用できます(単一ページアプリケーション)
静的リソースストレージ(ApplicationCache)
アプリケーションCacheはh 5静的資源キャッシュ方式である.この技術により、静的リソース/転送要求の構成を実現する、アプリケーションのロード速度を速め、サーバの負荷を低減することができる.
基本的な使い方 manifestプロファイル を導入 manifestファイル の構成書き込み更新バッファjs サーバ構成 manifestファイルを構成し、 に応答する.オンラインコードの配備時にmanifestバージョン番号と構成 を更新
以上の構成により、静的リソースキャッシュを実現することができる.
上記の図のように、
では、非同期ajaxリクエスト(ダイナミックリソース)はどのような方法で格納できますか?本格的なオフラインストレージを実現する.
動的リソースストレージ(WebSQL/IndexedDB)
フロントエンドデータベースを使用すると、ダイナミックリソースストレージを柔軟に制御できます.ここではindexedDBを使用していますが、なぜWebSQLを使用しないのですか?以前にオンラインチャットアプリケーションをした時、WebSQLを使ってチャット記録 を保存したことがある. WebSQLはすでに廃棄されています WebSQLは従来のリレーショナル・データベースであり、indexedDBは主流のNoSQL DB である.
基本的な使い方汎用データベースアクセスインタフェース を作成する fetch/ajaxメソッド を書き換える
chromeのweb toolでindexedDBを見ることができます
リクエストのたびにキャッシュされます
ネットを離れた後!非同期リクエストをシミュレートすることもできます!
「オフラインストレージ」:名前の通り、有線環境でデータ(静的リソース、動的リソースを含む)をキャッシュし、オフライン環境でもアプリケーションを正常に使用できます(単一ページアプリケーション)
静的リソースストレージ(ApplicationCache)
アプリケーションCacheはh 5静的資源キャッシュ方式である.この技術により、静的リソース/転送要求の構成を実現する、アプリケーションのロード速度を速め、サーバの負荷を低減することができる.
基本的な使い方
...
...
CACHE MANIFEST
# , js ,
# 2016972143
# : , ,
CACHE:
/dist/0.eda078350ef514670764.bundle.js
/dist/common.bundle.js?v=2016972143
/dist/df9f379beae2559b27044dcfdc0653ab.png?v=2016972143
/dist/home.bundle.js?v=2016972143
/dist/home.css?v=2016972143
uncached.js?v=2016972143
#cached.css
# : , ,
NETWORK:
*
#uncached.js
#uncached.css
# : , index.html , 404
FALLBACK:
#/v1/team/dirlists mock/team_dirlists.json
#/v1/team/app_filelist?isAdd=0&source=team&page=1&pageSize=10&sort=ftime&from=hiwebapp&fid=t293 mock/team_app_filelist.json
#index.html 404.html
// ,
// !!! : ,
(function () {
var cache = window.applicationCache;
cache.addEventListener('updateready', function(e) {
if (cache.status == cache.UPDATEREADY) {
// Browser downloaded a new app cache.
// if (confirm('A new version of this site is available. Load it?')) {
cache.swapCache();
window.location.reload();
// }
} else {
// Manifest didn't changed. Nothing new to server.
}
}, false);
cache.update()
}())
Content-Type: text/cache-manifest
Cache-Control: max-age=0
以上の構成により、静的リソースキャッシュを実現することができる.
上記の図のように、
from cache
のロード時間は他のネットワークリクエストよりずっと速い!このうちfetch/ajax
の要求は、応答結果が変化する可能性があるため、静的リソースによって記憶できない.では、非同期ajaxリクエスト(ダイナミックリソース)はどのような方法で格納できますか?本格的なオフラインストレージを実現する.
動的リソースストレージ(WebSQL/IndexedDB)
フロントエンドデータベースを使用すると、ダイナミックリソースストレージを柔軟に制御できます.ここではindexedDBを使用していますが、なぜWebSQLを使用しないのですか?
基本的な使い方
var indexedDB = window.indexedDB || window.msIndexedDB || window.mozIndexedDB || window.webkitIndexedDB;
// memCache ,
var req, db, memCache = {};
if(indexedDB) {
// version:2
req = indexedDB.open('ajax_cache', 2);
// caches
req.onsuccess = function (e) {
db = e.target.result;
if(!db.objectStoreNames.contains('caches')){
db.createObjectStore('caches', {keyPath: "id"});
}
}
//
req.onupgradeneeded=function(e){
var db=e.target.result;
if(!db.objectStoreNames.contains('caches')){
db.createObjectStore('caches', {keyPath: "id"});
}
console.log('DB version changed to ' + db.version);
};
req.onerror = function (err) {
console.error('indexedDB open failed. ', err)
}
}
export default {
isSupported: !!indexedDB,
set: (id, data) => {
var entity = {
id: id,
data: data
}
var transaction = db.transaction('caches', 'readwrite');
var store = transaction.objectStore('caches');
var req = store.put(entity);
req.onerror = () => {
console.error('put data failed. ', entity)
}
req.onsuccess = () => {
memCache[id] = data
console.info('put data successed. ', entity)
}
},
get: (id) => {
return new Promise((resolve, reject) => {
if(memCache[id]) {
resolve(memCache[id]);
return;
}
var transaction = db.transaction('caches', 'readwrite');
var store = transaction.objectStore('caches');
var req = store.get(id);
req.onerror = () => {
console.error('get data failed. ', id)
resolve()
}
req.onsuccess = (e) => {
var rlt = e.target.result;
console.info('get data successed. ', id, rlt)
resolve(rlt && rlt.data)
}
})
}
}
/* reset fetch function for offline be compatible*/
var fetch = require('isomorphic-fetch')
import {parse} from 'url'
var __fetch = fetch;
fetch = function (url) {
var rlt = parse(url, true);
function generateJson(json) {
return {
json: function () {
return json
}
}
}
function generateErrorJson() {
return generateJson({
errno: 500, errmsg: ' ',
result: {
files: []
}
})
}
var query = rlt.query;
// from
delete query.t;
delete query.from;
var id = rlt.pathname
var key = MyUtils.jsonToUrl(query)
if(MyUtils.isOffline()) { //
if(!id) {
return new Promise((resolve, reject) => {
resolve(generateErrorJson())
})
} else {
if(DB.isSupported) {
return DB.get(id).then(json => {
return (!json || !json[key])
? generateErrorJson()
: generateJson(json[key])
})
} else {
return new Promise((resolve, reject) => {
resolve(generateErrorJson())
})
}
}
} else {
return __fetch.apply(null, [].slice.call(arguments))
.then(res => res.json())
.then( (resJson) => {
if(DB.isSupported) {
var tmp = {};
tmp[key] = resJson;
DB.get(id).then(json => {
DB.set(id, Object.assign({}, json, tmp))
})
}
return generateJson(resJson)
}
)
}
}
chromeのweb toolでindexedDBを見ることができます
リクエストのたびにキャッシュされます
ネットを離れた後!非同期リクエストをシミュレートすることもできます!