Thought and Practice
of Offline First
オフライン・ファーストの
思想と実践


    株式会社オープンウェブ・テクノロジー
                  白石俊平
自己紹介

• 白石俊平と申します。
• HTML5開発者コミュニティhtml5j.org管理人(会員数5,000
  名超)
• HTML5とか勉強会主催(毎月一回、100名を動員)
• Google API Expert (HTML5)
• Microsoft Most Valuable Professional (IE9)
• Twitter: @Shumpei
• 著書:HTML5&API入門
Offline First – A better HTML5 User Experience
offlinefirst.com
Mobile First Web Second
Responsive Web Design
オフラインWeb時代の到来は・・・


   2014年?
白石俊平: 著
2007年
技術評論社刊
Why "Offline"?
なぜオフラインWebか?
オフライン
        スピード
でも使える




 ユーザビリティの向上
「Offline is a feature」




    Photo by methodship.com
「読む」中心のWebサイトでは


           メリット



 コスト
Google Slidesは
オフライン対応している




     "オフライン時の変更は、
     オンラインに戻った時に同期されます"
「編集」中心のWebアプリでは


 コスト



           メリット
オフラインの活路は
「モバイルアプリ」にあり!
         ネイティブ(Web)アプリ


   モバイルWebアプリ




    ハイブリッドアプリ
企業向けモバイルアプリの
  大半はHTML5に




Gartner Says by 2016, More Than 50 Percent of Mobile Apps Deployed Will be Hybrid
Building Blocks
オフラインWebを実現するAPI
オフラインWebアプリの基本




       Resources



                   Data
オフラインWebを実現するAPI

•   アプリケーションキャッシュ
•   Web Storage
•   Indexed Database API
•   File API
アプリケーションキャッシュ

         CACHE MANIFEST

         index.html
         index.css
         index.js




  ローカル          サーバ
アプリケーションキャッシュ

          CACHE MANIFEST

          index.html
 オフラインで   index.css
          index.js
  利用可能



  ローカル           サーバ
キャッシュマニフェスト


 ファイル先頭に「CACHE MANIFEST」

         1行に1URL

      "#"以降はコメント

    オンラインのアクセス先は
    NETWORKセクションに記述
キャッシュマニフェストが変更されていたら、
  キャッシュのリフレッシュが行われる
キャッシュマニフェストの例
 CACHE MANIFEST

 # v: 201302061503

 hello.html
 hello.css
 hello.js
 hello.jpg

 NETWORK:
 *



 <html manifest="site.appcache">
   ...
 </html>
アプリケーションキャッシュの
    「落とし穴」

  通常のHTTPキャッシュも怠らないで!

    キャッシュ容量は実装依存

    キャッシュは時間がかかる

     開発フローを改善しよう
Web Storage

• ブラウザ組み込みのキー・バリュースト
  ア
• 文字列しか保存できないが、JSONと組み
  合わせれば不便はあまりない。
• グローバル変数localStorageに、キーと
  値を保存するだけなので、非常に使いや
  すい。
Web Storageのコード例

// ストレージに値を保存
localStorage.person = JSON.stringify({
  name: "ご自分のお名前",
  age: ご自分の年齢
});
// 値を確認
alert(localStorage.person);
// オブジェクトに復元
var person = JSON.parse(localStorage.person);
alert(person.name);
alert(person.age);
Web Storageの
 「落とし穴」


文字列しか格納できない

  シンプルすぎる!

  同期APIしかない
Indexed Database API
•   ブラウザ組み込みのキー・バリューストア
•   WebStorageよりも複雑だが高機能
•   RDBのテーブルにあたるものがオブジェクトストア
•   JavaScriptオブジェクトをオブジェクトストアに対して
    そのまま読み書きできる。
Indexed Database API
           のコード例
var req = indexedDB.open(DB_NAME, latestVersion);
req.onsuccess = function(event) {
  db = req.result;
  var tx = db.transaction("FeedStore", "readonly");
  var feedEntryStore = tx.objectStore("FeedStore");
  var curReq = feedEntryStore.openCursor();
  var results = [];
  curReq.onsuccess = function() {
    var cursor = curReq.result;
    if (!cursor) {
      return;
    }
    var entry = cursor.value;
    results.push(entry);
    cursor.continue(); // カーソルを次に進める
  };
};
Indexed Database APIの
     「落とし穴」


    APIがあんまりイケてない

    RDBほどの柔軟性はない!

     SafariとOperaが未実装
File API

• Webアプリからファイルを読み書きする
  ためのAPI。
• 以下の3仕様からなる。
 – File API・・・ファイルの読み取りや基本的な
   インターフェースの定義
 – File API:Writer・・・ファイルの書き出し
 – File API:Systems and Directories・・・ファ
   イルシステムとディレクトリ構造
File API

• Chrome以外の実装が望めない状況。
• Google Docsのオフライン機能は、File
  APIを用いて実現されている。
Foundamental of
Offline First
オフライン・ファーストの勘所
1. アプリケーションとサーバを
       切り離す

     まずオフラインありき。



                 Resources
       サーバは、データを
     JSON APIで公開するのみ

                             Data
2. ラッパーを通じて
     Web APIを呼び出す
button.onclick = function() {
  $.get('/memo', function() {...});
};


            Ajax呼び出しを直接行わない。



button.onclick = function() {
  WebAPI.loadMemo(function() { ... });
};
3. 抽象化したオブジェクトを
   通じてデータを操作する
button.onclick = function() {
  WebAPI.loadMemo(function() { ... });
};


             データソースを抽象化する!



button.onclick = function() {
  Memo.get(function(memo) { ... });
};
User             Data          Web API
  Interface         Controller      Wrapper
Name:
E-mail:

          Submit




          データの永続化                データの同期
Demo
 デモ
Synchronization
データの同期について、
 ひとこと言いたい
同期処理の実装は

     難しい。
同期処理中にオフラインになったら?


   データ変更が衝突したら?


同期量を「必要最小限」に留めるには?
以前実現したアーキテクチャ




クライアント

         テーブ
          ルA
 UI                  同期
               ジャー
                     エン
                ナル
         テーブ         ジン
          ルB
Thank you!
ご清聴ありがとうございました!

    Follow me! @Shumpei

オフラインファーストの思想と実践