PjaxRubyist九州山崎重一郎            Rubyist九州2011年11月例会            2011年11月26日
Webアプリって いちいちページ遷移して使いにくい 反応が悪い そもそも、サーバ側でユーザの操作に対するアクションを処  理したり、ビューを生成したりする必要があるのか?                         サーバ      ...
Webアプリって ブラウザ側でやれることはブラウザ側でやれば? ひとつのアプリの中でページ遷移って必要? ブラウザ内で、DOM要素だけ処理すればいいんじゃない? 必要なデータだけJSONとかでサーバからもらえばいいじゃん。       ...
じゃあAjaxなの? リソースにちゃんとしたURLがついてないとブックマークできない、検索エンジンにひっかからないというか、そもそもそのリソースをWebで共有できないじゃないか REST の基本は重要!リソース状態の流通 (REpresen...
ブラウザ側のリソースと サーバ側のリソース Ajax的なシステムでも同一のURLが指すのは同一のリソース 直接サーバにURLでアクセスした場合 →     サーバからGET Ajax的に同じURLでアクセスした場合   → ブラウザ側で生...
ブラウザ側にリソース表現の 実体が構成された場合 Ajax的にDOM要素の構成でできたリソース その場合も仮想的にサーバ側にもリソースが存在しているよう  にしたい→ バックボタン、ブックマーク、検索エンジン、Web共有          ...
URLで直接的にリソースにアクセスした場合 もともとそのリソースはサーバに存在しているよ、という感じ ページの姿はブラウザ側で構成したものと全く同一にしたい                       サーバ                ...
Webブラウザの基本構成(かなりいいかげんですが...) <a href="">...</a> をクリックしたとき                  Webブラウザ  クリック                              htt...
Pjax 魔法のしくみ1 jQuery で、ブラウザの機能を抑制/入替 HTML5 のpushState でhistoryスタックに履歴をプッシュ                  Webブラウザ  クリック                ...
ブラウザの機能を抑制/入替え preventDefault()  <!doctype html>  <html>  <head>  <meta charset="UTF-8">  <title>preventDefalut()のテスト</ti...
HTML5 の history.pushState history.pushState(historyオブジェクト, タイトル, URL); ブラウザの閲覧履歴スタックに強引にタイトルやURLを強引にプッシュ → とりあえずブックマークできる...
Pjax = jQueryの jquery.pjax.js  これがPjaxのオリジナル pushState + Ajax = Pjax https://github.com/defunkt/jquery-pjax   直接URLを入れても ...
jquery.pjax.js リクエストヘッダに HTTP_X_PJAX           を含める サーバ側は、HTTP_X_PJAXのときはAjax的にデータだけ送る そうでなければ、レイアウト付きのHTMLを返す          ...
jquery.pjax.jsの使用例 sinatraの場合   # -*- coding: utf-8 -*-   require sinatra   get / do    erb "<h1>トップページです</h1>", :layout ...
サーバ側の魔法の種明かし リクエストヘッダのHTTP_X_PJAXの有無チェックとレイアウ  トの抑制判定  get / do   erb "<h1>トップページ</h1>", :layout => !env[HTTP_X_PJAX]  en...
PjaxはRails3.2 から標準になる 利点は明らかだから当然 今後のWebアプリケーションは基本的にページ遷移しなくなる Rails流のMVCも見直しが必要 コントロールやビュー生成の大部分をcoffeeScriptでやるの? P...
でも、なぜこんなにうまくいくのか? historyに pushState を追加しただけなのに? なにか基本的な原理がありそう
Rubyistの目線からの妄想 historyへのプッシュは、クロージャによるメモ化に似ている  理論的なかっこいいアプローチもあるかも クロージャによるメモ化 関数の入力と出力の視点からの意味は変わらない 既存の計算結果のキャッシュを使う...
Upcoming SlideShare
Loading in …5
×

Pjax1

1,380 views
1,268 views

Published on

Pjax1

  1. 1. PjaxRubyist九州山崎重一郎 Rubyist九州2011年11月例会 2011年11月26日
  2. 2. Webアプリって いちいちページ遷移して使いにくい 反応が悪い そもそも、サーバ側でユーザの操作に対するアクションを処 理したり、ビューを生成したりする必要があるのか? サーバ アク ション ビュー データとビュー 生成 HTML
  3. 3. Webアプリって ブラウザ側でやれることはブラウザ側でやれば? ひとつのアプリの中でページ遷移って必要? ブラウザ内で、DOM要素だけ処理すればいいんじゃない? 必要なデータだけJSONとかでサーバからもらえばいいじゃん。 サーバ アク ション データのみ JSON等 ビュー 生成
  4. 4. じゃあAjaxなの? リソースにちゃんとしたURLがついてないとブックマークできない、検索エンジンにひっかからないというか、そもそもそのリソースをWebで共有できないじゃないか REST の基本は重要!リソース状態の流通 (REpresentational State Transfer) → サーバをステートレスに保ちながら、リソースの状態は表現で きる 例:リソースへのアクセス権限状態(OAuthのアクセストークンなど)ほら! やっぱりAjaxじゃだめじゃん
  5. 5. ブラウザ側のリソースと サーバ側のリソース Ajax的なシステムでも同一のURLが指すのは同一のリソース 直接サーバにURLでアクセスした場合 → サーバからGET Ajax的に同じURLでアクセスした場合 → ブラウザ側で生成 サーバ リソース アク リソース ション リソース リソース リソース ビュー リソース 生成
  6. 6. ブラウザ側にリソース表現の 実体が構成された場合 Ajax的にDOM要素の構成でできたリソース その場合も仮想的にサーバ側にもリソースが存在しているよう にしたい→ バックボタン、ブックマーク、検索エンジン、Web共有 サーバ リソース アク リソース ション リソース リソース リソース ビュー リソース 生成
  7. 7. URLで直接的にリソースにアクセスした場合 もともとそのリソースはサーバに存在しているよ、という感じ ページの姿はブラウザ側で構成したものと全く同一にしたい サーバ リソース リソース リソース
  8. 8. Webブラウザの基本構成(かなりいいかげんですが...) <a href="">...</a> をクリックしたとき Webブラウザ クリック http GET など エンティティ マネージャ LF (ヘッダ) CR サーバ LF (ボディ) CR historyスタック 表示 レンダラ DOM <h1>aaa</h1><p>...
  9. 9. Pjax 魔法のしくみ1 jQuery で、ブラウザの機能を抑制/入替 HTML5 のpushState でhistoryスタックに履歴をプッシュ Webブラウザ クリック http GET などをしたつもり エンティティ マネージャ XjQuery preventDefault( ) historyスタック HTML5 pushState 表示 レンダラ DOM
  10. 10. ブラウザの機能を抑制/入替え preventDefault() <!doctype html> <html> <head> <meta charset="UTF-8"> <title>preventDefalut()のテスト</title> <script type="text/javascript" src=jquery-1.7.js></script> </head> <body> <h1>preventDefault()のテスト</h1> <p> <a id="enable" href="http://www.cacanet.org">このリンク</a>は有効にされています。 <a id="disable" href="http://www.cacanet.org">このリンク</a>は無効にされています。 </p> <p id="message"></p> <script type="text/javascript"> $("#disable").click(function (e) { e.preventDefault(); $("#message").html("ほら、ページ遷移しないでしょ?"); }); </script> </body> </html>
  11. 11. HTML5 の history.pushState history.pushState(historyオブジェクト, タイトル, URL); ブラウザの閲覧履歴スタックに強引にタイトルやURLを強引にプッシュ → とりあえずブックマークできる。 <html><head><meta charset="UTF-8"> <title>最初のページ</title> <script> function ps() {history.pushState(null,null,"http://rubyist.org/");} </script> </head> <body> <h1>pushSateのテスト</h1> <form> <input type="button" value="URLに注目" onclick="ps()" /> </form> </body></html>
  12. 12. Pjax = jQueryの jquery.pjax.js これがPjaxのオリジナル pushState + Ajax = Pjax https://github.com/defunkt/jquery-pjax 直接URLを入れても 同じページが表示される デモページ:http://pjax.heroku.com/
  13. 13. jquery.pjax.js リクエストヘッダに HTTP_X_PJAX を含める サーバ側は、HTTP_X_PJAXのときはAjax的にデータだけ送る そうでなければ、レイアウト付きのHTMLを返す Webブラウザ クリック エンティティ マネージャ X HTTP_X_PJAX jQuery jquery.pjax.js サーバ historyスタック HTML5 データ pushState だけ 表示 レンダラ DOM
  14. 14. jquery.pjax.jsの使用例 sinatraの場合 # -*- coding: utf-8 -*- require sinatra get / do erb "<h1>トップページです</h1>", :layout => !env[HTTP_X_PJAX] end get /hello do erb "<h1>こんにちは!<%=Time.now%></h1>", :layout => !env[HTTP_X_PJAX] end __END__ @@layout <!doctype html><html><head> <title><%= @title %></title> <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.min.js"></script> <script type="text/javascript" src="http://pjax.heroku.com/jquery.pjax.js"></script> <script type="text/javascript">$("a.pjax").pjax("#main");</script> </head> <body> <ul> <li><a href="/" class="pjax">ホーム</a></li> <li><a href="/hello" class="pjax">あいさつ</a></li> </ul> <div id="main"><%= yield %></div> </body></html>
  15. 15. サーバ側の魔法の種明かし リクエストヘッダのHTTP_X_PJAXの有無チェックとレイアウ トの抑制判定 get / do erb "<h1>トップページ</h1>", :layout => !env[HTTP_X_PJAX] end Ajax的にDOM要素を更新する部分の指定(divでyieldを囲む) <div id="main"><%= yield %></div> a タグ(pjaxクラスの)に対するpjaxの適用 <li><a href="/" class="pjax">ホーム</a></li> <li><a href="/hello" class="pjax">あいさつ</a></li> <script type="text/javascript">$("a.pjax").pjax("#main");</script>
  16. 16. PjaxはRails3.2 から標準になる 利点は明らかだから当然 今後のWebアプリケーションは基本的にページ遷移しなくなる Rails流のMVCも見直しが必要 コントロールやビュー生成の大部分をcoffeeScriptでやるの? Pjax を基本にした、すっきり新しいWebアプリフレームワーク を新規設計した方がはやい
  17. 17. でも、なぜこんなにうまくいくのか? historyに pushState を追加しただけなのに? なにか基本的な原理がありそう
  18. 18. Rubyistの目線からの妄想 historyへのプッシュは、クロージャによるメモ化に似ている 理論的なかっこいいアプローチもあるかも クロージャによるメモ化 関数の入力と出力の視点からの意味は変わらない 既存の計算結果のキャッシュを使うか、関数の処理を実際に計算するか Pjax 同じURLにアクセスしたときのページの姿は変わらない ブラウザ側でページ要素のみを構成するか、サーバからページ全体を 持ってくるか Haskellの人は、「それはxxモナドだよ」とか言うかも...

×