Client Side Cache

3,149 views

Published on

IE6+ で使える DOM Storage の話。
Yokohama.pm #3 での発表資料

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,149
On SlideShare
0
From Embeds
0
Number of Embeds
10
Actions
Shares
0
Downloads
17
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Client Side Cache

  1. 1. Introduction DOM Storage and Inside Ex DOM Storage library Toru Yamaguchi id:ZIGOROu <zigorou@cpan.org>
  2. 2. アジェンダ <ul><li>DOM Storage ってなんだよ! </li></ul><ul><ul><li>localStorage と sessionStorage </li></ul></ul><ul><ul><li>Cookie との違い </li></ul></ul><ul><li>Inside Ex DOM Storage </li></ul><ul><ul><li>Behavior の基礎知識 </li></ul></ul><ul><ul><li>userData Behavior </li></ul></ul><ul><ul><li>HTML Component Behavior </li></ul></ul><ul><ul><li>onpropertychange </li></ul></ul><ul><li>Ex DOM Storage のこれから </li></ul>
  3. 3. DOM Storage とは <ul><li>DOM Storage とは何か </li></ul><ul><ul><li>DOM Storage とは JavaScript から構造化されたデータをクライアントサイドに保存する技術で HTML 5 で規定されている </li></ul></ul><ul><ul><ul><li>http://www.whatwg.org/specs/web-apps/current-work/#structured-client-side-storage </li></ul></ul></ul><ul><ul><li>現時点では IE8, Fx2, Fx3, Safari 4 などで利用出来る </li></ul></ul><ul><ul><li>DOM Storage には永続データ保存用の localStorage とセッションデータ保存用の sessionStorage がある </li></ul></ul><ul><ul><li>共に key-value 形式でデータを String として保存出来る </li></ul></ul>
  4. 4. localStorage <ul><li>localStorage </li></ul><ul><ul><li>host 単位 で有効な永続的なクライアントサイドキャッシュです </li></ul></ul>if (localStorage.foo) { // 2 回目以降のアクセス console.log(localStorage.foo); } else { // 初回のアクセス localStorage.foo = “bar”; }
  5. 5. sessionStorage <ul><li>sessionStorage </li></ul><ul><ul><li>host 単位で有効で、ブラウザを閉じると消えます </li></ul></ul><ul><ul><li>また sessionStorage は window オブジェクトごとに割り当てられます </li></ul></ul>
  6. 6. Storage interface <ul><li>Storage interface </li></ul>interface Storage { readonly attribute unsigned long length ; [IndexGetter] DOMString key (in unsigned long index); [NameGetter] DOMString getItem (in DOMString key); [NameSetter] void setItem (in DOMString key, in DOMString data); [XXX] void removeItem (in DOMString key); void clear (); };
  7. 7. StorageEvent interface <ul><li>Storage interface </li></ul>interface Storage { readonly attribute unsigned long length ; [IndexGetter] DOMString key (in unsigned long index); [NameGetter] DOMString getItem (in DOMString key); [NameSetter] void setItem (in DOMString key, in DOMString data); [XXX] void removeItem (in DOMString key); void clear (); };
  8. 8. Storage interface <ul><li>Storage interface </li></ul>interface StorageEvent : Event { readonly attribute DOMString key ; readonly attribute DOMString oldValue ; readonly attribute DOMString newValue; readonly attribute DOMString url ; readonly attribute Window source ; void initStorageEvent ( in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString keyArg, in DOMString oldValueArg, in DOMString newValueArg, in DOMString urlArg, in Window sourceArg); void initStorageEventNS ( in DOMString namespaceURI, in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString keyArg, in DOMString oldValueArg, in DOMString newValueArg, in DOMString urlArg, in Window sourceArg); };
  9. 9. Storage event (1) <ul><li>Storage event </li></ul><ul><ul><li>setItem(), removeItem() 相当の処理が実行された場合に storage イベントが発生します。 </li></ul></ul><ul><ul><ul><li>対象となった key 及び、新旧の値が event オブジェクトに入ってます </li></ul></ul></ul><ul><ul><li>clear() メソッドが実行された場合も storage イベントが発生します。 </li></ul></ul><ul><ul><ul><li>event.key, event.oldValue, event.newValue プロパティは null になっている </li></ul></ul></ul><ul><ul><li>localStorage の場合は、同一ホストで共有されるので、 storage イベントは単独の window だけに通知されるのではなく、関係する全ての window に fire されます。 </li></ul></ul><ul><ul><ul><li>event.source プロパティに localStorage への変更を行った window オブジェクトが入ります </li></ul></ul></ul>
  10. 10. Storage event (2) <ul><li>sample </li></ul>var l = function (evt) { console.log(“key: ” + evt.key); console.log(“oldValue: ” + evt.oldValue); console.log(“newValue: “ + evt.newValue); } ; window .addEventListener( &quot;storage&quot; , l, false );
  11. 11. Cookie vs DOM Storage (1) <ul><li>有効期限 </li></ul><ul><ul><li>Cookie は expire を指定すれば任意の期間まで指定でき、指定しない場合はブラウザを閉じると消える </li></ul></ul><ul><ul><li>localStorage は明示的に消さない限り永続的。 sessionStorage はブラウザを閉じると消える。 </li></ul></ul><ul><ul><ul><li>つまり指定時刻で消えるような Storage を使いたければ localStorage を何らかの方法で管理する必要がある </li></ul></ul></ul>
  12. 12. Cookie vs DOM Storage (2) <ul><li>容量 </li></ul><ul><ul><li>IE の場合、 Cookie は 4096 byte までしか保存出来ず、また key-value のペアは 20 が上限。 </li></ul></ul><ul><ul><li>IE の場合、 DOM Storage には 10MB ほど保存できる </li></ul></ul><ul><li>API </li></ul><ul><ul><li>Cookie は document.cookie プロパティを用いるが getter/setter の挙動が極めてキモイ </li></ul></ul><ul><ul><li>DOM Storage は通常の Object をハッシュのように扱うのと同じように ( つまりプロパティ代入が ) 使えるし、またきちんとメソッド (getItem, setItem, removeItem, clear) 経由でも操作出来る </li></ul></ul>
  13. 13. Cookie vs DOM Storage (3) <ul><li>図解で分かる Cookie vs DOM Storage の共有 </li></ul>same host ( domain, path は設定してない状態 ) Window 1 Window 2 Window 3 Window 4 Window 5 localStorage / Cookie sessionStorage
  14. 14. IE6, 7 で使えない?Ex DOM Storage で出来るよ <ul><li>Ex DOM Storage </li></ul><ul><ul><li>IE6, IE7 で使える DOM Storage ライブラリ </li></ul></ul><ul><ul><li>拙作です </li></ul></ul><ul><ul><li>http://coderepos.org/share/wiki/ExDOMStorage </li></ul></ul><ul><li>今日のメインの話 </li></ul><ul><ul><li>Inside Ex DOM Storage </li></ul></ul><ul><ul><li>問題点と今後について </li></ul></ul>
  15. 15. Ex DOM Storage の中身の概略 <ul><li>Ex DOM Storage で利用しているニッチ技術の概要 </li></ul><ul><ul><li>userData Behavior </li></ul></ul><ul><ul><li>HTML Component Behavior </li></ul></ul><ul><ul><li>onpropertychange による代入検出 </li></ul></ul>
  16. 16. Behavior の基礎知識 <ul><li>Behavior とは何か </li></ul><ul><ul><li>後から任意の要素にプロパティ、メソッド、イベントやイベントハンドラを追加できる枠組みを DHTML Behavior と言う </li></ul></ul><ul><ul><li>既に幾つかの Behavior Library が組み込まれている </li></ul></ul><ul><ul><ul><li>#default#userData </li></ul></ul></ul><ul><ul><ul><li>#default#VML </li></ul></ul></ul><ul><ul><li>カスタムの Behavior を HTML Component と言う </li></ul></ul><ul><ul><ul><li>Mozilla の XBL (XML Binding Language) は HTC のパクリ </li></ul></ul></ul>
  17. 17. userData Behavior (1) <ul><li>userData Behavior とは </li></ul><ul><ul><li>IE にデフォルトで付いてくる Behavior ライブラリの一つ </li></ul></ul><ul><ul><li>もろにクライアントサイドストレージ、使い方も超簡単 </li></ul></ul>element.addBehavior( &quot;#default#userData&quot; ); element.load( “my Storage ” ); // 読み込み element.setAttribute( “myData” , “blah blah” ); // 値の設定 element.save( “my Storage ” ); // 書き込み
  18. 18. userData Behavior (2) <ul><li>userData Behavior の有効範囲 </li></ul><ul><ul><li>host 単位で保存されるので DOM Storage と同じ。 </li></ul></ul><ul><li>key-value の設定 </li></ul><ul><ul><li>最初は attribute として key を表現しようと思ったのだが、 userData Behavior を適用した element の場合、 attribute の列挙が上手く行かない ( 仕様っぽぃ ) </li></ul></ul><ul><ul><ul><li>JSON で突っ込む事に。 </li></ul></ul></ul>
  19. 19. userData Behavior (3) <ul><li>Lock 出来ない </li></ul>Window (1) Window (2) load(skey) setAttribute(key, value) save(skey) load(skey) この時点で、 value には JSON データが入る。 { foo: “blah” } とかそういう値。 Window (1) の load() 前のデータが取れてしまう。以下略><
  20. 20. HTML Component Behavior (1) <ul><li>HTC のサンプル </li></ul><?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?> <public:component xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xmlns:public=&quot;urn:HTMLComponent&quot;> <script type=&quot;text/javascript“ src=“/path/to/src.jp”></script> <public:attach event=&quot;oncontentready&quot; onevent=&quot;handlers.contentready(event);“ for=&quot;element&quot; /> <public:attach event=&quot;onresize“ onevent=&quot;handlers.resize(event);“ for=&quot;window&quot; /> </public:component>
  21. 21. HTC Component Behavior (2) <ul><li>HTC の利点 </li></ul><ul><ul><li>要素の挙動を比較的自由に決める事が出来る </li></ul></ul><ul><ul><ul><li>指定した width を少なくとも確保するような挙動とか (c.f. min-width) </li></ul></ul></ul><ul><ul><ul><li>任意のメソッドを生やしたり </li></ul></ul></ul><ul><ul><ul><li>あるいは property に対する getter/setter を特定の JavaScript メソッドに割り当てたり </li></ul></ul></ul><ul><ul><ul><ul><li>IE は defineGetter, defineSetter が存在しない </li></ul></ul></ul></ul><ul><ul><ul><ul><li>readonly のプロパティが作れ、さらに計算結果などを返せる </li></ul></ul></ul></ul><ul><ul><ul><ul><li>length プロパティとかに使える </li></ul></ul></ul></ul>
  22. 22. HTML Component Behavior (3) <ul><li>HTC の配信時の注意 </li></ul><ul><ul><li>HTC は text/x-component で配信 </li></ul></ul><ul><ul><ul><li>AddType text/x-component .htc </li></ul></ul></ul><ul><li>HTC のロード - 3 種類 </li></ul><ul><ul><li>PI 命令として </li></ul></ul><ul><ul><ul><li><?import namespace=“svg” implementation=“svg.htc” ?> </li></ul></ul></ul><ul><ul><li>element.addBehavior(“foo.htc”) </li></ul></ul><ul><ul><li>CSS として </li></ul></ul><ul><ul><ul><li>div.foo { behavior: url(“foo.htc”); } </li></ul></ul></ul>
  23. 23. HTML Component Behavior (4) <ul><li>localStorage, sessionStorage オブジェクトの表現 </li></ul><ul><ul><li>実は script 要素を 二つ document.createElement() で作成して、 head 要素内に appendChild() して、この script 要素に HTC を element.addBehavior() している。 </li></ul></ul><ul><ul><li>理由は二つ </li></ul></ul><ul><ul><ul><li>property への getter/setter を使いたいから </li></ul></ul></ul><ul><ul><ul><li>onpropertychange を localStorage.foo = “blah” のような代入文の検出に使いたいから </li></ul></ul></ul>
  24. 24. Ex DOM Storage の HTC ファイル (1) <ul><li>Ex DOM Storage の HTC </li></ul><!DOCTYPE html> <public:component xmlns=&quot;http://www.w3.org/1999/xhtml“ xmlns:public=&quot;urn:HTMLComponent&quot;> <public:property name=&quot;length&quot; get=&quot;getLength&quot; /> <public:property name=&quot;remainingSpace&quot; get=&quot;getRemainingSpace&quot; /> <public:method name=&quot;clear&quot; /> <public:method name=&quot;getItem&quot; /> <public:method name=&quot;key&quot; /> <public:method name=&quot;removeItem&quot; /> <public:method name=&quot;setItem&quot; /> <public:attach event=&quot;onreadystatechange&quot; for=&quot;element&quot; onevent=&quot;initialize();&quot; /> <public:attach event=&quot;onpropertychange&quot; for=&quot;element&quot; onevent=&quot;syncronize(window.event);&quot; /> <script type=&quot;text/javascript&quot; src=&quot;../src/json2.js&quot;></script> <script type=&quot;text/javascript&quot; src=&quot;../src/exdomstorage_impl.js&quot;></script> </public:component>
  25. 25. Ex DOM Storage の HTC ファイル (2) <ul><li>ちなみに冒頭にあった DOCTYPE 宣言 </li></ul><ul><ul><li>document.compatMode が HTC にも存在する </li></ul></ul><ul><ul><li>DOCTYPE 宣言や xml 宣言に影響される </li></ul></ul><ul><ul><li>CSS1Compat じゃないと互換モードなので、 DOM 操作に色々支障が出る </li></ul></ul><ul><ul><li>なので HTC は XML 形式ですが HTML として DOCTYPE 宣言を入れると吉 </li></ul></ul>
  26. 26. Ex DOM Storage の HTC 実装部 <ul><li>実装部 </li></ul>/* * Implementation Storage Interface * storage.length と言うアクセスの際に * 必ず getLength() が呼ばれる */ function getLength() { var length = 0; for (var p in storage) length++; return length; }
  27. 27. onpropertychange イベント <ul><li>onpropertychange イベント </li></ul><ul><ul><li>element オブジェクトのプロパティに対する変更が行われた際に発火 (fire) します </li></ul></ul><ul><ul><li>Storage オブジェクトを script 要素に対して addBehavior() したオブジェクトで表現しているので、 onpropertychange イベントで storage.foo = “blah” のような代入をイベントハンドラで捕捉できる </li></ul></ul><ul><ul><ul><li>これをもって storage への反映、さらに storage イベントの発火を行うことが出来る </li></ul></ul></ul>
  28. 28. Ex DOM Storage Known Issue <ul><li>storage イベントが同一 host な window 全てに対して通知出来ていない </li></ul><ul><ul><li>異なる window 間での通信はどうやる? </li></ul></ul><ul><ul><li>document.cookie なら設定したら即座に共有される </li></ul></ul><ul><ul><ul><li>setInterval で監視する </li></ul></ul></ul><ul><li>sessionStorage が window ごとにユニークになっていない </li></ul><ul><ul><li>window.name なら window ごとにユニークで、遷移しても値を保持し続ける </li></ul></ul><ul><ul><li>ここに uuid でも突っ込んで、それをキーにして userData に書き込む </li></ul></ul>
  29. 29. まとめ <ul><li>DOM Storage はもうすぐクロスブラウザな技術 </li></ul><ul><ul><li>IE8, Fx2, Fx3, Safari 4 で既に使える技術 </li></ul></ul><ul><ul><li>Ex DOM Storage が完成度高くなると IE6+ になる </li></ul></ul><ul><ul><li>Opera たん。。。。。 </li></ul></ul><ul><li>Known Issue な部分はまだ未実装 </li></ul><ul><ul><li>coderepos にソースあるんで、興味ある人はコミットしてホスィなと。 </li></ul></ul><ul><li>HTML Component 面白いよ </li></ul><ul><ul><li>ちょっとやればすぐに分かるので、 IE で CSS の挙動がプギャーとかあったら書いてみるのといいかも </li></ul></ul><ul><ul><li>Pathtraq でも一部使ってるw (XBL も ) </li></ul></ul>

×