GreaseMonkeyによるAjaxのすすめ(準備編)

 ウェブサイトが複雑化し、アクセス解析や広告なども含めると1ページにつき無数のHTTPリクエストが行なわれるようになった昨今。いくらブロードバンドが普及し、端末やブラウザのレンダリング能力も向上したとは言っても、ウェブサイトの読み込みとレンダリングの遅さに困らされる事がなくなったとは決して言えません(だってウェブサイト側がそれをフルに利用しようとするんだもの)。
 これらのうち、実際にどこに時間がかかるかと言うと……多くの場合、そのウェブサイトで共通の部分……例えば全てのページで使っているスクリプトの読み込みだとか、ヘッダーやフッターのレイアウト処理だったりするわけです。
 じゃあ、共通する部分を読み込み直さないようにすればいいじゃない、というのが今回のお話です。方法は単純。GreaseMonkeyを使って、必要部分だけをAjaxに書き換えちまおうぜ。

 理論上はどんなページでもAjax化しようと思えばできるはずですが、今回は試しに、CFlatのホームページ(http://www.cflat-inc.com/)をAjax化してみたいと思います[1]。今回は準備編。

GreaseMonkeyとは

 GreaseMonkeyとは、ウェブページ単位でユーザースクリプトを設定・実行するためのFirefoxプラグインです。イメージとしては、指定した条件のウェブページに、予め指定したJavaScriptをscriptタグで挿入してくれるようなモノ。ユーザースクリプトは自作もできる他、オンラインで配布されているものをインストールすることもできます[2]。
 ユーザースクリプトの拡張子は*.user.js。

 GreaseMonkey自体はFirefox用のプラグインですが、Internet ExplorerSafari用にも同等のプラグインがある他、Google ChromeOperaではブラウザの標準機能としてユーザースクリプトを直接読み込めるようです[3]。

Ajax化の準備

 まずは、Ajaxな処理を埋め込むために、何が必要なのかを調べてみましょう(GreaseMonkeyは既に導入済みとして)。

(1) Ajax化の必要な範囲を定める
 簡単に「Ajax化する」と言ってはのけましたが、実際にどのURLの、どの要素をAjaxに書き換えるのか、考えなくてはなりません。とりあえず今回は、http://www.cflat-inc.com/ にアクセスした時だけAjax化するものとしておきましょう。

 どの要素をAjax化するかを知るには、幾つものページを移動して、共通部分と変化する部分を地道に調べる必要があります。
 実際にCFlatのホームページをざっと調べてみると、変更がある部分は次の要素だけ(CSSセレクタ形式で記載)のようだ、ということがわかります。

・#menu-nav > li(各liのclass属性のみが変化)
・#header-gra
・body > .breadcrumbs(HOMEには存在しない)
・#contents

 もしCFlatのホームページがリニューアルされてHTMLの構造が変わってしまったら、それはその時に作り直す事にしましょう。その際CFlatでは、一切の責任を負いません(CFlatに限らず、ユーザーが勝手に導入したスクリプトの責任がサイト管理者ではなくユーザーに帰属するのは自明だと思いますが……それがわからない輩は決してユーザースクリプトなんて使わないこと)。

(2) jQuery・Activity Indicator・jQuery Formの導入
 Ajax処理を、XMLHttpRequestを使って真面目に実装してやってもいいのですが、面倒なのでjQueryhttp://jquery.com/ )のAjax処理を使います。また、Ajax通信中であることを示すためのぐるぐるを表示する用に、Activity Indicator( http://neteye.github.io/activity-indicator.html )もあると良いでしょう。
 また、SNSや掲示板等の場合は、投稿処理をAjax化するためにjQuery Form( http://plugins.jquery.com/form/ )を利用しておきましょう。

 対象のページに既にこれらのJavaScriptが導入済みであれば、それを使うことができます。
 実際にCFlatのホームページを調べてみると、window.jQueryおよびwindow.jQuery.fn.ajaxSubmitが定義されているため、jQueryjQuery Formも導入済みであることがわかりました。が、window.jQuery.fn.activityは定義されていなかったので、Activity Indicatorは未導入と判断できます。

 ブラウザのバージョンによっては、jQuery hashchange eventが欲しくなるかもしれません。

GreaseMonkeyスクリプトの新規作成

 GreaseMonkeyの「ユーザースクリプト新規作成」メニューを実行すると、幾つかの入力画面が出ます(FirefoxGreaseMonkey以外での場合は割愛)。

・名前:一目でどんなスクリプトかわかれば問題ありません。今回は安易に「CFlat AJAXer」としました。
名前空間:一意な名前をつけます。ユーザースクリプトを配布する予定があるのであれば配布元のURLを使っておけばよいでしょうが、配布しないのであれば被らないものであれば何でもいいです。私は、今回のように「対象とするURL?スクリプト名」にする事にしています。
・説明:スクリプトの詳細説明です。スクリプトを自作した場合には不要でしょうが。
・実行するページ:今回はCFlatのトップページのみなので「http://www.cflat-inc.com/」「http://www.cflat-inc.com/#*」だけとしましたが、それ以下のページにも全てこのスクリプトを適用させるのなら「http://www.cflat-inc.com/*」とワイルドカードの*をつけてます。/^https?://www\.cflat-inc\.com/*$/ のように前後を//で囲むと正規表現で指定できますが、正規表現中の/は\/のようにエスケープする必要はありません。
・実行しないページ:実行するページの条件に当てはまっても、さらに実行しないページの条件にも当てはまる場合はこのスクリプトは実行されません。

 OKボタンを押すと、次のようなスクリプトがエディタで開かれると思います。

// ==UserScript==
// @name        CFlat AJAXer
// @namespace   http://www.cflat-inc.com/?ajaxer
// @description CFlatのホームページをAJAX化する
// @include     http://www.cflat-inc.com/
// @version     1
// ==/UserScript==

 ここで、@version以外は先ほどの入力画面で設定したものです(@versionは、最初は1)。
 エディタ上でスクリプトを保存した後に対象ページをリロードすると、ユーザースクリプトの内容が反映されるようになります[4]。

GreaseMonkeyスクリプトを書く(準備編)

 それでは次に、jQuery等を使うように設定してゆきましょう。
 本来ウェブページに存在しないスクリプトを利用するために、@require文を追加します。今回は、以下のうちで必要になるのはActivity Indicatorだけでしたね。

jQuery(記事執筆時の最新版のv2.0.3にしてありますが、バージョンはお好みで)

// @require     http://code.jquery.com/jquery-2.0.3.min.js

jQuery Form(記事執筆時の最新版の3.25.0-2013.01.18にしてありますが(ry)

// @require     http://malsup.github.io/jquery.form.js

・Activity Indicator

// @require     https://raw.github.com/neteye/jquery-plugins/master/activity-indicator/activity-indicator.js

 @requireされたスクリプトは毎回指定したURLから読み込まれるのではなく、一度読み込まれたらローカルに保存されます。jQueryのCDNが落ちたりはしないかとハラハラする心配は(最初以外)ありません。

// ==UserScript==
// @name        CFlat AJAXer
// @namespace   http://www.cflat-inc.com/?ajaxer
// @description CFlatのホームページをAJAX化する
// @include     http://www.cflat-inc.com/
// @require     https://raw.github.com/neteye/jquery-plugins/master/activity-indicator/activity-indicator.js
// @version     1
// ==/UserScript==

 これで、各種の準備が整いました。
 試しに、上記のコードの下に次のコードを追加してみて、「HOME」の上で変なのがくるくる回っていれば、ここまでのところは成功です。

jQuery('.current-menu-item').activity();

 以降、次回に続く。


※1 実用性を考えれば掲示板だとかSNSとかをAjax化したいところなのですが、他人様のサイトを改変してみせる訳にも行かないので自重。必要なら、同じような手順で作ってみて下さい。
※2 ある意味、わざとXSSを起こしてウェブサイトを改変しているようなものなので、不用意にスクリプトをインストールするとどうなるかは……言わずもがな。
※3 GreaseMonkey専用の関数(GM_xxx())には互換性がない場合も。ただし、それらを使わないのであれば概ね問題ないようです。
※4 エラーがあるとそこで止まりますが、FireFoxの開発者ツールもFirebugも、GreaseMonkeyのエラーは表示してくれません。良い方法、どなたかご存知ありませんか?