I believe every developer knows the importance of caching. There is a caching background (memcached, xcache, etc.) from beginning to end to reduce the pressure on the db. Content delivery network (CDN) caches want your browser to cache resources that are loaded more than once. Of course, there is client-side caching, so you don't repeat expensive operations (even algorithms or large calculations).
This is a good javascript client solution, optional support for HTML5 local storage.
Starting Simple
function CacheProvider() {
// values will be stored here
this._cache = {};
}Feature detect on local storage
try {
CacheProvider.hasLocalStorage = ('localStorage' in window) && window['localStorage'] !== null;
} catch (ex) {
CacheProvider.hasLocalStorage = false;
}
The main reason for using try catch here is that although firefox supports this attribute, it needs to be in about:config Set it up and turn it on, otherwise an error will be reported. So a simple if else cannot meet the needs.
Below we will add support for the object local storage mechanism. This technique is based on a good article by Christopher Blizzard
Saving data with local storage – for which those who didn't know, you can only store string's into local storage. Thus we have this…
in / out JSON parsing
if (CacheProvider .hasLocalStorage) {
Storage.prototype.setObject = function(key, value) {
this.setItem(key, JSON.stringify(value));
};
Storage. prototype.getObject = function(key) {
return JSON.parse(this.getItem(key));
};
}
Now we have our three The core methods are get, set, and clear.
Core class functionality
CacheProvider.prototype = {
/**
* {String} k - the key
* {Boolean} local - get this from local storage?
* {Boolean} o - is the value you put in local storage an object?
*/
get: function(k, local, o) {
if (local && CacheProvider.hasLocalStorage) {
var action = o ? 'getObject' : 'getItem';
return localStorage[action](k) || undefined;
} else {
return this._cache[ k] || undefined;
}
},
/**
* {String} k - the key
* {Object} v - any kind of value you want to store
* however only objects and strings are allowed in local storage
* {Boolean} local - put this in local storage
*/
set: function(k, v, local) {
if (local && CacheProvider.hasLocalStorage) {
if (typeof v !== 'string')) {
// make assumption if it's not a string, then we're storing an object
localStorage.setObject(k, v);
} else {
try {
localStorage.setItem(k, v);
} catch (ex) {
if (ex.name == 'QUOTA_EXCEEDED_ERR') {
// developer needs to figure out what to start invalidating
throw new Exception(v);
return;
}
}
}
} else {
// put in our local object
this._cache[k] = v;
}
// return our newly cached item
return v;
},
/**
* {String} k - the key
* {Boolean} local - put this in local storage
* {Boolean} o - is this an object you want to put in local storage?
*/
clear: function(k, local, o) {
if (local && CacheProvider.hasLocalStorage) {
localStorage.removeItem(k);
}
// delete in both caches - doesn't hurt.
delete this._cache[k];
}
};
How to use?
Note that at the beginning of this article, it was said that Cache Provider is optional local storage. First, let us look at an example without local storage:
getElementsByClassName
var cache = new CacheProvider;
window.getElementsByClassName = getElementsByClassName || function(c) {
var reg = cache.get(c) || cache.set(c, new RegExp("(?:^|s )" c "(?:s |$)"));
var elements = document.getElementsByTagName('*');
var results = [];
for (var i = 0; i < elements.length; i ) {
if (elements[i].className.match(reg)) {
results.push(elements[i]);
}
}
return results;
};
Note: Next time you call a class function, it will be replaced by a pre-compiled regular expression Enough to construct an expression.
Another example: For example, for large applications that require i18n, you can cache a compiled html string into local storage.
var i18nCache = new CacheProvider;
if (i18nCache.get('topnav')) {
$('#nav').html(i18nCache.get('topnav'));
} else {
ajax('top-nav .tmpl', function(html) {
i18nCache.set('topnav', html);
$('#nav').html(i18nCache.get('topnav'));
} );
}
In addition, you can do a lot of things like caching external resources locally, come on :)