a brief introduction to local storage
TRANSCRIPT
A Brief Introduction to localStorage
Shouqiang Gong - @StuPig_me
13年7月19⽇日星期五
API
Read more: localStorage spec
13年7月19⽇日星期五
APIMETHOD ARGS RETURNS
setItem string key, string value
getItem string key string value
removeItem string key
clear
key int index string key
length int length
Read more: localStorage spec
13年7月19⽇日星期五
APIMETHOD ARGS RETURNS
setItem string key, string value
getItem string key string value
removeItem string key
clear
key int index string key
length int length
Read more: localStorage spec
13年7月19⽇日星期五
APIMETHOD ARGS RETURNS
setItem string key, string value
getItem string key string value
removeItem string key
clear
key int index string key
length int length
Read more: localStorage spec
13年7月19⽇日星期五
APIMETHOD ARGS RETURNS
setItem string key, string value
getItem string key string value
removeItem string key
clear
key int index string key
length int length
Read more: localStorage spec
13年7月19⽇日星期五
APIMETHOD ARGS RETURNS
setItem string key, string value
getItem string key string value
removeItem string key
clear
key int index string key
length int length
Read more: localStorage spec
13年7月19⽇日星期五
APIMETHOD ARGS RETURNS
setItem string key, string value
getItem string key string value
removeItem string key
clear
key int index string key
length int length
Read more: localStorage spec
13年7月19⽇日星期五
APIMETHOD ARGS RETURNS
setItem string key, string value
getItem string key string value
removeItem string key
clear
key int index string key
length int length
Read more: localStorage spec
13年7月19⽇日星期五
Snippet
13年7月19⽇日星期五
Snippet
// original API
localStorage.setItem('decade', '00s');
localStorage.setItem('song', JSON.stringify({artist: 'ColdPlay', title: 'Yellow'}));
var decade = localStorage.getItem('decade');var song = JSON.parse(localStorage.getItem('song'));
alert('Best song in the ' + decade + ' was ' + song.title + ' by ' + song.artist);
13年7月19⽇日星期五
Store.js
other libraies: locache, LawnChair
13年7月19⽇日星期五
Store.js
// 3rd library - store.js// https://github.com/marcuswestin/store.js
store.set('decade', '00s')store.set('song', {artist: 'ColdPlay', title: 'Yellow'});
var decade = store.get('decade');var song = store.get('song');
alert('Best song in the ' + decade + ' was ' + song.title + ' by ' + song.artist);
other libraies: locache, LawnChair
13年7月19⽇日星期五
Event
Read more: storage event spec
13年7月19⽇日星期五
Event
PROPERTY TYPE
key string
oldValue any
newValue any
url string
*timestamp double
Read more: storage event spec
13年7月19⽇日星期五
Event
PROPERTY TYPE
key string
oldValue any
newValue any
url string
*timestamp double
Read more: storage event spec
13年7月19⽇日星期五
Event
PROPERTY TYPE
key string
oldValue any
newValue any
url string
*timestamp double
Read more: storage event spec
13年7月19⽇日星期五
Event
PROPERTY TYPE
key string
oldValue any
newValue any
url string
*timestamp double
Read more: storage event spec
13年7月19⽇日星期五
Event
PROPERTY TYPE
key string
oldValue any
newValue any
url string
*timestamp double
Read more: storage event spec
13年7月19⽇日星期五
Event
PROPERTY TYPE
key string
oldValue any
newValue any
url string
*timestamp double
Read more: storage event spec
13年7月19⽇日星期五
StorageEvent
other libraies: StorageEvent
13年7月19⽇日星期五
StorageEvent// StorageEvent doesn’t bubble and is not cancelable
window.addEventListener('storage', function (e) { if (!e) e = window.event;}, false)
// trigger the event manuallyvar evt = document.createEvent('StorageEvent');// args: type canBubble cancelBubble key oldVaule // newValue url storageAreaevt.initStorageEvent('StorageEvent', ...);window.dispatch(evt);
other libraies: StorageEvent
13年7月19⽇日星期五
Compatibility
13年7月19⽇日星期五
Compatibilityworks well in major browsers...
13年7月19⽇日星期五
Compatibilityworks well in major browsers...
13年7月19⽇日星期五
Capacity
Read more: localStorage capacity
13年7月19⽇日星期五
Capacityhas a limited capacity (2-5MB) per subdomain...
Read more: localStorage capacity
13年7月19⽇日星期五
Capacityhas a limited capacity (2-5MB) per subdomain...
Browser localStorage sessionStorage globalStorage
Android2.2 - 4.2 2.49M unlimited
(except 3.0) none
iPhone3.1 - 6.1 2.49M 2.49M none
Chrome Mobile16 - 28 2.49M 2.49M none
IE Mobile9 - 10 4.75M 4.75M none
Read more: localStorage capacity
13年7月19⽇日星期五
Capacityhas a limited capacity (2-5MB) per subdomain...
Browser localStorage sessionStorage globalStorage
Android2.2 - 4.2 2.49M unlimited
(except 3.0) none
iPhone3.1 - 6.1 2.49M 2.49M none
Chrome Mobile16 - 28 2.49M 2.49M none
IE Mobile9 - 10 4.75M 4.75M none
Read more: localStorage capacity
13年7月19⽇日星期五
Capacityhas a limited capacity (2-5MB) per subdomain...
Browser localStorage sessionStorage globalStorage
Android2.2 - 4.2 2.49M unlimited
(except 3.0) none
iPhone3.1 - 6.1 2.49M 2.49M none
Chrome Mobile16 - 28 2.49M 2.49M none
IE Mobile9 - 10 4.75M 4.75M none
Read more: localStorage capacity
13年7月19⽇日星期五
Capacityhas a limited capacity (2-5MB) per subdomain...
Browser localStorage sessionStorage globalStorage
Android2.2 - 4.2 2.49M unlimited
(except 3.0) none
iPhone3.1 - 6.1 2.49M 2.49M none
Chrome Mobile16 - 28 2.49M 2.49M none
IE Mobile9 - 10 4.75M 4.75M none
Read more: localStorage capacity
13年7月19⽇日星期五
Capacityhas a limited capacity (2-5MB) per subdomain...
Browser localStorage sessionStorage globalStorage
Android2.2 - 4.2 2.49M unlimited
(except 3.0) none
iPhone3.1 - 6.1 2.49M 2.49M none
Chrome Mobile16 - 28 2.49M 2.49M none
IE Mobile9 - 10 4.75M 4.75M none
Read more: localStorage capacity
13年7月19⽇日星期五
Scope
13年7月19⽇日星期五
Scope• is scoped to the subdomain
13年7月19⽇日星期五
Scope• is scoped to the subdomain
• values on Secure (SSL) pages are isolated
13年7月19⽇日星期五
Scope• is scoped to the subdomain
• values on Secure (SSL) pages are isolated
• sessionStorage values survive some browser restarts
13年7月19⽇日星期五
Scope• is scoped to the subdomain
• values on Secure (SSL) pages are isolated
• sessionStorage values survive some browser restarts
• values created in “incognito” mode are isolated
13年7月19⽇日星期五
Usage
13年7月19⽇日星期五
Usage
• persistent user data
13年7月19⽇日星期五
Usage
• persistent user data
• persistent app state
13年7月19⽇日星期五
Usage
• persistent user data
• persistent app state
• filled-in forms
13年7月19⽇日星期五
Usage
• persistent user data
• persistent app state
• filled-in forms
• client cache
13年7月19⽇日星期五
Persistent User Datasave user profile...
try: Dillinger
13年7月19⽇日星期五
Persistent User Datasave user profile...
try: Dillinger
13年7月19⽇日星期五
Persistent App Stateremember checked options...
try: JSHint
13年7月19⽇日星期五
Persistent App Stateremember checked options...
try: JSHint
13年7月19⽇日星期五
Filled-in Forms
try: autoStorage Savify
13年7月19⽇日星期五
Filled-in Formsremember author information...
try: autoStorage Savify
13年7月19⽇日星期五
Filled-in Formsremember author information...
try: autoStorage Savify
13年7月19⽇日星期五
Client Cache
Specialized libraries: lscache, Inject, Basket.js
13年7月19⽇日星期五
Client Cache
• cache API results
Specialized libraries: lscache, Inject, Basket.js
13年7月19⽇日星期五
Client Cache
• cache API results
• cache AJAX results
Specialized libraries: lscache, Inject, Basket.js
13年7月19⽇日星期五
Client Cache
• cache API results
• cache AJAX results
• cache resources
Specialized libraries: lscache, Inject, Basket.js
13年7月19⽇日星期五
Abusage
Read more: localStorage performance
13年7月19⽇日星期五
Abusage• serialize unnecessarily
Read more: localStorage performance
13年7月19⽇日星期五
Abusage• serialize unnecessarily
• excessive keys
Read more: localStorage performance
13年7月19⽇日星期五
Abusage• serialize unnecessarily
• excessive keys
• excessive gets/sets
Read more: localStorage performance
13年7月19⽇日星期五
Abusage• serialize unnecessarily
• excessive keys
• excessive gets/sets
• block the UI
Read more: localStorage performance
13年7月19⽇日星期五
Abusage• serialize unnecessarily
• excessive keys
• excessive gets/sets
• block the UI
• assume localStorage always works
Read more: localStorage performance
13年7月19⽇日星期五
Abusage• serialize unnecessarily
• excessive keys
• excessive gets/sets
• block the UI
• assume localStorage always works
• use key names that collide
Read more: localStorage performance
13年7月19⽇日星期五
Don’t Serialize Unnessarily
try: Primitives vs. Strings JSON.stringify
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
function store(key, val) { localStorage.setItem(key, JSON.stringify(val));}store('num', 1);store('on', true);store('name', 'pamela');
try: Primitives vs. Strings JSON.stringify
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
function store(key, val) { localStorage.setItem(key, JSON.stringify(val));}store('num', 1);store('on', true);store('name', 'pamela');
after:function store(key, val) { localStorage.setItem(key, val);}store('num', '1');store('on', 'true');store('name', 'pamela');
try: Primitives vs. Strings JSON.stringify
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
function store(key, val) { localStorage.setItem(key, JSON.stringify(val));}store('num', 1);store('on', true);store('name', 'pamela');
after:function store(key, val) { localStorage.setItem(key, val);}store('num', '1');store('on', 'true');store('name', 'pamela');
try: Primitives vs. Strings JSON.stringify
use strings where possible
13年7月19⽇日星期五
Don’t Serialize Unnessarily
try: String split/join vs. JSON Stringify
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
var fruits = ['apple', 'banana', 'orange'];localStorage.setItem('fruits', fruits.join(','));var fruits = localStorage.getItem('fruits').split(',');
try: String split/join vs. JSON Stringify
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
var fruits = ['apple', 'banana', 'orange'];localStorage.setItem('fruits', fruits.join(','));var fruits = localStorage.getItem('fruits').split(',');
after:
var fruits = ['apple', 'banana', 'orange'];localStorage.setItem('fruits', JSON.stringify(fruits));var fruits = JSON.parse(localStorage.getItem('fruits'));
try: String split/join vs. JSON Stringify
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
var fruits = ['apple', 'banana', 'orange'];localStorage.setItem('fruits', fruits.join(','));var fruits = localStorage.getItem('fruits').split(',');
after:
var fruits = ['apple', 'banana', 'orange'];localStorage.setItem('fruits', JSON.stringify(fruits));var fruits = JSON.parse(localStorage.getItem('fruits'));
use own serializer if its faster
try: String split/join vs. JSON Stringify
13年7月19⽇日星期五
Don’t Serialize Unnessarily
try: Multiple keys vs. JSON2 keys vs. JSON
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
localStorage.setItem('location', JSON.stringify({'state': 'texas', 'city': 'austin'}));
try: Multiple keys vs. JSON2 keys vs. JSON
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
localStorage.setItem('location', JSON.stringify({'state': 'texas', 'city': 'austin'}));
after:
localStorage.setItem('location-state', 'texas');localStorage.setItem('location-city', 'austin');
try: Multiple keys vs. JSON2 keys vs. JSON
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
localStorage.setItem('location', JSON.stringify({'state': 'texas', 'city': 'austin'}));
after:
localStorage.setItem('location-state', 'texas');localStorage.setItem('location-city', 'austin');
try: Multiple keys vs. JSON2 keys vs. JSON
store multiple strings instead of 1 object if it is faster
13年7月19⽇日星期五
Don’t Serialize Unnessarily
try: 1 long key vs. multiple short keys
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
localStorage.setItem('first', 'pamela');localStorage.setItem('middle', 'susan');localStorage.setItem('last', 'fox');
try: 1 long key vs. multiple short keys
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
localStorage.setItem('first', 'pamela');localStorage.setItem('middle', 'susan');localStorage.setItem('last', 'fox');
after:
localStorage.setItem('name', 'pamela susan fox');
try: 1 long key vs. multiple short keys
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
localStorage.setItem('first', 'pamela');localStorage.setItem('middle', 'susan');localStorage.setItem('last', 'fox');
after:
localStorage.setItem('name', 'pamela susan fox');
try: 1 long key vs. multiple short keys
combine logical keys commonly accessed together
13年7月19⽇日星期五
Don’t Serialize Unnessarily
try: Caching in local memoryCaching in the DOM
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
$('input[type="checkbox"]').click(function() { localStorage.setItem($(this).attr('name'), $(this).is(':checked'));});
try: Caching in local memoryCaching in the DOM
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
$('input[type="checkbox"]').click(function() { localStorage.setItem($(this).attr('name'), $(this).is(':checked'));});
after:window.onunload = function() { $('input[type="checkbox"]').each(function() { localStorage.setItem($(this).attr('name'), $(this).is(':checked')); });};
try: Caching in local memoryCaching in the DOM
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
$('input[type="checkbox"]').click(function() { localStorage.setItem($(this).attr('name'), $(this).is(':checked'));});
after:window.onunload = function() { $('input[type="checkbox"]').each(function() { localStorage.setItem($(this).attr('name'), $(this).is(':checked')); });};
try: Caching in local memoryCaching in the DOM
cache data in local memory/DOM,and only get/set on window load/unload
13年7月19⽇日星期五
Don’t Serialize Unnessarily
try: Not blocking the UI in tight js loops
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
<head><script> $('#name').html(localStorage.getItem('name'));</script></head>
try: Not blocking the UI in tight js loops
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
<head><script> $('#name').html(localStorage.getItem('name'));</script></head>
after:<body></body><script>window.onload = function() { $('#name').html(localStorage.getItem('name'));};</script>
try: Not blocking the UI in tight js loops
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
<head><script> $('#name').html(localStorage.getItem('name'));</script></head>
after:<body></body><script>window.onload = function() { $('#name').html(localStorage.getItem('name'));};</script>
try: Not blocking the UI in tight js loops
defer using localStorage until onload
13年7月19⽇日星期五
Don’t Serialize Unnessarily
try: Nicholas Zakas: Responsive Interfaces
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
$('button').click(function() { var name = localStorage.getItem('name'); $('#name').html(name);});
try: Nicholas Zakas: Responsive Interfaces
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
$('button').click(function() { var name = localStorage.getItem('name'); $('#name').html(name);});
after:$('button').click(function() { window.setTimeout(function() { var name = localStorage.getItem('name'); $('#name').html(name); }, 10);});
try: Nicholas Zakas: Responsive Interfaces
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
$('button').click(function() { var name = localStorage.getItem('name'); $('#name').html(name);});
after:$('button').click(function() { window.setTimeout(function() { var name = localStorage.getItem('name'); $('#name').html(name); }, 10);});
try: Nicholas Zakas: Responsive Interfaces
use setTimeout to defer localStorage access
13年7月19⽇日星期五
Don’t Serialize Unnessarily
try: jQuery throttle/debounce plugin2 localStorage tips
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
$('textarea').keydown(function() { localStorage.setItem('text', $(this).text());});
try: jQuery throttle/debounce plugin2 localStorage tips
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
$('textarea').keydown(function() { localStorage.setItem('text', $(this).text());});
after:$('textarea').keydown(function() { $.debounce(250, function() { localStorage.setItem('text', $(this).text()); });});
try: jQuery throttle/debounce plugin2 localStorage tips
13年7月19⽇日星期五
Don’t Serialize Unnessarilybefore:
$('textarea').keydown(function() { localStorage.setItem('text', $(this).text());});
after:$('textarea').keydown(function() { $.debounce(250, function() { localStorage.setItem('text', $(this).text()); });});
try: jQuery throttle/debounce plugin2 localStorage tips
throttle or debounce to avoid repetitive gets/sets
13年7月19⽇日星期五
Don’t Serialize Unnessarily
13年7月19⽇日星期五
Don’t Serialize Unnessarilybad:
localStorage.setItem('bla', 'bla');
13年7月19⽇日星期五
Don’t Serialize Unnessarilybad:
localStorage.setItem('bla', 'bla');
better:if (window.localStorage) { localStorage.setItem('bla', 'bla');}
13年7月19⽇日星期五
Don’t Serialize Unnessarilybad:
localStorage.setItem('bla', 'bla');
better:if (window.localStorage) { localStorage.setItem('bla', 'bla');}
best:if (window.localStorage) { try { localStorage.setItem('bla', 'bla'); } catch(e) { if (e.name === 'QUOTA_EXCEEDED_ERR' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') { } else { } }}
13年7月19⽇日星期五
Don’t Serialize Unnessarilybad:
localStorage.setItem('bla', 'bla');
better:if (window.localStorage) { localStorage.setItem('bla', 'bla');}
best:if (window.localStorage) { try { localStorage.setItem('bla', 'bla'); } catch(e) { if (e.name === 'QUOTA_EXCEEDED_ERR' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') { } else { } }}
check for feature support
13年7月19⽇日星期五
Don’t Serialize Unnessarily
try: long vs. short names
13年7月19⽇日星期五
Don’t Serialize Unnessarilybad:
localStorage.setItem('name', 'pamela');
try: long vs. short names
13年7月19⽇日星期五
Don’t Serialize Unnessarilybad:
localStorage.setItem('name', 'pamela');
better:localStorage.setItem('conference-speaker-first-name', 'pamela');
try: long vs. short names
13年7月19⽇日星期五
Don’t Serialize Unnessarilybad:
localStorage.setItem('name', 'pamela');
better:localStorage.setItem('conference-speaker-first-name', 'pamela');
best:lscache.setBucket('conference-speaker');lscache.set('first-name', 'pamela');
try: long vs. short names
13年7月19⽇日星期五
Don’t Serialize Unnessarilybad:
localStorage.setItem('name', 'pamela');
better:localStorage.setItem('conference-speaker-first-name', 'pamela');
best:lscache.setBucket('conference-speaker');lscache.set('first-name', 'pamela');
try: long vs. short names
use highliy descriptive keys with pseudo namespaces
13年7月19⽇日星期五
QA
13年7月19⽇日星期五