メインコンテンツへ移動

Pjax (pushState and Ajax)

無料2015-09-22#Front-End#JS#pjax#pushState & Ajax#single page app#spa#pjax详解#pjax原理

Pjaxとは何か、どんな役割があるのか、どう使うのか、なぜ使うのか?

1. Pjaxとは?

Pjax = history.pushState + Ajax
     = history.pushState + Async JS + XML(xhr?)

BOMオブジェクトの history が強化されました。主に履歴スタックの操作に関するもので、以前は replacego などしかなく、これらはページ全体を遷移・更新してしまっていました。現在は pushStatereplaceState といった、純粋に履歴スタックを操作するメソッドが追加され、副作用(ページの遷移・更新)なしに履歴スタックの内容のみを変更できるようになりました。

historyオブジェクトの詳細については、MDN History を参照してください。

2. Pjaxにはどんな役割があるのか?

1. 初期のシングルページアプリケーション (SPA)

ページの更新はリソースを浪費するだけでなく(多くの関連ページではコンテンツの大部分が共通しており、重複部分を再読み込みする必要はありません)、ユーザー体験にも影響を与えます(ローディング画面の連続など)。部分更新はローディングによるユーザー体験への悪影響を避けることができ、Ajaxの概念が登場して以来、サイト全体をシングルページアプリケーション(Single Page App、略称SPA)にする試みが始まりました。AjaxでJSONをリクエストし、部分更新でデータを表示する形式ですが、初期のSPAには多くの欠点がありました:

  • 最大の問題:ページコンテンツとURLが対応しない

    これは致命的な欠点です。ユーザーが見ているコンテンツとアドレスバーのURLが対応していないため、コンテンツをシェア・拡散することができません(シェアと拡散は非常に重要です)。また、ブラウザの「進む」「戻る」ボタンもユーザーの期待通りに動作しません。

  • 次に:SEOを損なう

    純粋なAjaxで実装されたSPAは、SEOに極めてネガティブな影響を与えます。ページ上の多くのコンテンツがAjaxリクエスト後にJavaScriptによって制御・表示されるため、クローラー(検索エンジン)がこれらのコンテンツを見ることができず、インデックスや収集が行われません。

2. pretty AJAX URL

SEO問題を解決するために、Googleは「不格好な(名前はpretty AJAX URLなのに…)」手法を提案しました: #!(ハッシュバン)です。

かつてTwitterが1ヶ月ほど採用していましたが、ユーザーから不格好だというフィードバックがあり、後に廃止されました。このURL形式は確かに前述の2番目の問題を解決できますが、検索エンジンの協力が必要です。Googleはこの方式を認め、Googleのクローラーは mydomain.com/index.html#!article1mydomain.com/index.html#!article2 を2つの異なるページとして扱います。サーバー側でこれらの特殊なURLリクエストに対して対応するページを返せば、SEO問題は解消されます。

しかし、1番目の問題、すなわちページコンテンツとURLが対応しないという問題は残ったままでした。そこで登場したのがPjaxです。

3. Pjax

W3Cは新しいAPIを提案し、historyによる履歴スタックの制御能力を強化しました。これにより、アドレスバーのURLを直接変更できるようになり、ようやくページコンテンツとURLが完全に対応するようになりました。

部分更新が成功するたびに history.pushState を呼び出してアドレスバーのURLを同期更新(履歴スタックを維持)します。これらのURLはすべて、直接アクセス可能なページに対応しています。部分更新のアクションは a タグによってトリガーされ、JavaScriptでデフォルトの遷移をインターセプトし、Ajaxでデータをリクエストして表示します。ユーザー側では部分更新によるスムーズな体験が得られ、クローラー側では通常の a タグによるページ遷移として認識されます。ページに表示される内容は、常にそのURLに直接アクセスして得られる内容と一致するため、致命的な欠点は解消されました。

もし各ブラウザのサポートが良好であれば、Pjaxはシングルページアプリケーションを完璧にサポートできます。ブラウザが新しいAPIをサポートしていない場合は、クローラーとして扱えばよいでしょう(現時点では決定的なポリフィルはないようで、jQueryプラグインでも限界があります)。CSS/JSの競合やメモリリークなどはSPA自体の問題であり、成熟したSPAソリューションであれば回避可能です。

3. Pjaxはどう使うのか?

核心となるのは、2つのメソッドと1つのイベントです:

  • history.pushState(state, title, url);

  • history.replaceState(state, title, url);

  • popstate

ここで state パラメータは任意のオブジェクトで、 history.state から取得できます。 title パラメータは特に役割はなく、ブラウザ側でも認識されませんpushreplace の違いは、前者が指定したURLをスタックに積み、後者が現在のスタックの最上位要素を入れ替える点です。ブラウザの「進む」「戻る」は popstate をトリガーするため、その中で history.state のデータに基づいて適切な処理を行います。

先人による簡潔なデモがあります: ajax与HTML5 history pushState/replaceState实例

また、以下のようなオープンソースライブラリも利用可能です:

  • jQuery pjax:最近(2015-09-22)も更新されています。

  • history.js:2年前に更新が止まっていますが、使い勝手が良いと言われています。

  • welefen/pjax:主要なJSライブラリでのPjaxの使い方。

4. なぜPjaxを使うのか?

SEOに影響を与えずに、部分更新 + ローカルキャッシュによって、これまでにない高速な体験を提供できる。これがPjaxの絶対的な強みです。

Pjaxは純粋なモバイル向けではないシングルページアプリケーションに適しており、スムーズなユーザー体験を実現できます。また、カプセル化されたPjaxコンポーネントは、キャッシュ、ローカルストレージ、アニメーションなどの追加機能をサポートしており、非常に便利です。

モバイルページでは通常、頻繁かつ大規模なコンテンツ更新は発生せず、SEOを考慮する必要も少ないため、直接Ajaxを使用するだけで十分な場合が多いです。

5. Pjaxの事例

参考文献

コメント

コメントはまだありません

コメントを書く