Head Cleaner (仮) – ここまでのまとめ

さて、先日から「Head Cleaner (仮)」を、夜半になると Twitter 上で公開しては修正、機能アップを繰り返してきたのですが、盛り込みたかった機能もかなり盛り込めたので、これより熟成期間に入ります。
で、熟成期間に入る前に今までの経緯をまとめておきます。
まずは、このプラグインの基本的な動作原理。

  1. WordPress のテーマテンプレート inex.php や single.php に <?php get_header(); ?> って記述があると思いますが、これが呼ばれた時に動作を開始します。
    この時は、まだ ob_start で、バッファ取得開始するだけ。
  2. header.php の <?php wp_head(); ?> が呼ばれた時点でバッファ取得を終了し、書き出された文字列を解析して整形します。

やってることは、これだけ。
まだまだ開発途上のプラグインですが、人柱になっていただいている方々、ありがとうございます m(_ _)m
不具合は色々と出てきましたが、私は元気です。

さて、では以降は今までの経緯のまとめ。

Ver.0.1.x 公開

スゴイのが、できてしまったまずは、最初のバージョン 0.1.0 、このバージョンでの、主要機能は4つ。

  1. <head> 内の余計な空白、コメントを削除してタグを整列させる。
  2. インライン JavaScript、CSS を外部ファイルとして書き出します。
  3. ブラウザが IE6以外の場合のみ、先頭に XML 宣言を付加。
  4. 話題の <link rel="canonical" /> タグを付加。

この時は、まだ (X)HTML の解析に SimpleXML を使用していたので、XML 的に残念なヘッダを吐いているプラグインがあると動作しませんでした。

作成後、Twitter でつぶやいたら @hiromasa に食いつかれました。
コレだけでも、十分にインパクトはあったようです。

Ver.0.2.x JavaScript 結合

xml 的に残念だと駄目なの?(笑)いや〜ん次のバージョン 0.2.xでは、内部リンクしている JavaScript とインライン JavaScript をすべて結合して、一ファイルにする機能を付加しました。
また、<head> 内の JavaScript をフッタ部に移動させる機能も追加しました。
これで YSlow 値が急上昇。
気を良くして、ブログにエントリしました。

ただし、このバージョンでも相変わらず SimpleXML で (X)HTML の解析をしていたので、私のところとhiromasaさんのテスト環境ぐらいでしか、まともに動作しませんでした。

Ver.0.3.x Simple HTML DOM Parser 導入

Head Cleaner の Simple HTML DOM Parser 版できたよ。続く、バージョン 0.3.xでは、(X)HTML の解析に SimpleXML ではなく、PHP Simple HTML DOM Parser を使用するように変更しました。
これで、かなりのサイトで動作するようになりました。
このバージョン辺りから、kohaku さんや、yutaka さんのサイトで導入してもらい始めました。
こんな、まだまだ不具合の多いα版なのに人柱ありがとうございます m(_ _)m

また、ゆりこさんからの指摘で、JavaScript、CSS に拡張子が「.gz」なファイルを使用していると Safari で、正常に認識できないことが発覚。
実は JavaScript、CSS の gzip 圧縮転送は、ブラウザのリファラを確認して HTTP_ACCEPT_ENCODING に gzip が設定されているかどうかだけで判断し、gzip 圧縮転送に対応していたら、JavaScript、CSS のファイル名を .gz 付きに置換していたのですが
どうやら、拡張子が「.gz」のファイルの Content-Type は、「text/css」でも「text/javascript」でもないため Safari では正常に認識してくれないようです。
# Safari 以外のブラウザが、お節介にも認識してくれてる方がおかしいような気も

これについては、各ブラウザの仕様が将来変更されて、正しい Content-Type でないと認識できなくなるかも知れないので、将来のバージョンでは他の方法で対応するように検討中です。

ver.0.4.x CSS 結合

Head Cleaner 0.4.0 は CSS も結合してしまうらしいぞ。そして、バージョン 0.4.xでは、内部リンクしている CSS もすべて結合して一ファイルにするようになりました。
CSS 内では URL を相対パスで書いてあることが多く、結合して基準パスが変わると、まともに動作しなくなってしまうおそれがあったため、これまでのバージョンでは手をつけなかったのですが、相対パスを絶対パスに変換することで結合できるようにしました。
まぁ、この機能は次バージョンでの新機能に対する布石だったわけですが

ver.0.5.x CSS 最適化、JavaScript 圧縮

Head Cleaner Ver.0.5.0 は悪魔のツールになってしまった。 さて、現在のところの最新版バージョン 0.5.xでは、ついに CSS, JavaScript の圧縮に対応しました。

CSS は CSSTidy、JavaScript は jsmin-php を使用することによって、ソースのファイルサイズ自体を小さくします。
もう、すでにヘッダの整形プラグインではなくて、WordPress サイトのフロントエンド高速化プラグインと言っても過言では無いくらいの機能追加ではないでしょうか?
これにより、私のところではトップページのファイル転送量が 226.4kb → 170.5kb と -25% のダイエット成功。
凄いぜキット!

ただ yutaka さんのところで、私の作ったWPプラグイン「WP-lightpop」が、一部ブラウザ(IE, Chrome)で動作しなくなることが判明。
私のところでは、正常に動作しているのになんで yutaka さんのところだけ

色々と試してみた結果、どうやら Prototype.js ver.1.6.0.x と、jQuery ver.1.3.2 の組み合わせが悪いようです。
Head Cleaner (仮) では、CSS セレクタが高速になった jQuery 1.3.2 をロードするようになっているのですが、これがうまくないようです。

次バージョンで Prototype.js, jQuery.js のバージョンを判断して適切なものを使うように修正します。
また JavaScript ライブラリの重複ロード問題についても対応します。
たぶん、この機能が盛り込めたら最後のβ版になるでしょう。

開発期間的にはホンの1週間だけでしたが Twitter やら(@hiromasa@binsan@kohaku_ori@darumen@satchin1226 thx)、ブログのコメント欄やら(ゆりこさんJ君ajin さん thx)で、色々とご助言・テストありがとうございました。
非常に楽しい開発期間でした。こんなスタイルのプログラミングも楽しくて良いですね。

Head Cleaner (仮) を取り上げていただいたエントリ

最後に Head Cleaner (仮) を取り上げていただいた方のエントリを列挙しておきます。
こんな、未完成のプラグインを取り上げて紹介していただき、ありがとうございました m(_ _)m

Head Cleaner (仮) – ここまでのまとめ」への13件のフィードバック

  1. かっきー

    はじめまして、Head Cleaner について少し疑問が出てきたので
    お暇なときにでも教えていただけるとありがたいです。

    Head Cleaner(以下HC)の設定で
    ※複数のCSSとjavascriptを結合させ
    ※キャッシュさせる
    という設定にした場合、HCのキャッシュファイル名はどういった場合に変更になるのでしょうか?

    CSSとjavascriptのファイルを前回のものと比較してその都度キャッシュファイル名が決まっているのか?
    ファイルのバイト数の比較でバイト数に変更があった場合のみキャッシュファイル名を変更しているのか?

    どうなんだろー・・・とおもいました。

    というのが、この部分が分かれば expires header で
    ExpiresByType text/css “access plus 1 month”
    ExpiresByType text/javascript “access plus 1 month”

    と設定しても問題ないなっ!とおもったので・・・。

    をかもとさん、おしえてください><

    返信
    1. をかもと 投稿作成者

      かっきーさん、はじめまして。

      Head Cleaner(以下HC)の設定で
      ※複数のCSSとjavascriptを結合させ
      ※キャッシュさせる
      という設定にした場合、HCのキャッシュファイル名はどういった場合に変更になるのでしょうか?

      CSSとjavascriptのファイルを前回のものと比較してその都度キャッシュファイル名が決まっているのか?
      ファイルのバイト数の比較でバイト数に変更があった場合のみキャッシュファイル名を変更しているのか?

      キャッシュファイル名は、すべてのファイルの「ファイル名」+「ファイルのタイムスタンプ」とインラインCSS(or JavaScript)の内容すべてを結合した文字列を md5() 関数に渡すことで決定しています。
      なので、ファイルのバイト数が異なっていても、タイムスタンプが同じであれば、同一のファイルとして認識しています。

      返信
      1. かっきー

        なるほどー!ありがとうございます!!

        (キャッシュファイル名→)ファイルのタイムスタンプできまってくる!ということは、
        ファイルを上書き保存したタイミングで新たなキャッシュファイル名が登場するということですね。

        (そういう認識でいいのかなぁー・・・汗;)

        もし、上記の認識でいいのならば、
        expires header を 30 day にしておいても問題ないですね。

        ということは、Head Cleaner は神プラグインです。
        素晴らしい、プラグインをありがとうございます。

        PS:をかもと さんのファンになりそうです。

        返信
        1. をかもと 投稿作成者

          かっきーさん、どもです。

          (キャッシュファイル名→)ファイルのタイムスタンプできまってくる!ということは、
          ファイルを上書き保存したタイミングで新たなキャッシュファイル名が登場するということですね。

          (そういう認識でいいのかなぁー・・・汗;)

          そうです。
          ただ、この方式は一つ難点があって、古いキャッシュファイルを自動で削除しないのです。
          なので、キャッシュファイルが段々溜まっていきます。
          たまに削除してやってください。

          返信
  2. hbirds

    早速、リターンありがとうございました。
    了解しました 😛
    近日中に、すべてのプラグインを停止して実験してみます。
    競合しているプラグインが確認できたらまたコメントします。
    ありがとうございました。

    返信
  3. hbirds

    Head Cleaner!!すばらしいプラグインをありがとうございます。
    Super Cache とともに使わせていただいております。
    ・・・が、なぜかTopページのソースを見てみるとTopページだけうまく働いていないようです。
    他のページでは、きれいにCSSやJSが再配置されているのに・・・。
    私のTopページはもともとのテーマのPage.phpを多少いじってtop_page.phpとしてテンプレートに指定し、
    管理画面の表示設定でフロントページとしてTopとセットしています。
    get header() やget footer()もちゃんとありますが、何故なのでしょう?
    自分ではスキルがなく、もし思い当たる原因があればご教示いただきたく、よろしくお願いします。

    返信
    1. をかもと 投稿作成者

      hbirds さん、はじめまして。

      なぜかTopページのソースを見てみるとTopページだけうまく働いていないようです。
      他のページでは、きれいにCSSやJSが再配置されているのに・・・。
      私のTopページはもともとのテーマのPage.phpを多少いじってtop_page.phpとしてテンプレートに指定し、
      管理画面の表示設定でフロントページとしてTopとセットしています。
      get header() やget footer()もちゃんとありますが、何故なのでしょう?

      うーん、ちょっと分からないです。get_header() があれば、動作するようには作成してあるんですが…

      お使いのプラグインのうちのどれかと競合しているのかもしれません。
      Head Cleaner 以外のすべてのプラグインを停止して、Head Cleaner が動作するか確認してみてください。
      この段階で Head Cleaner が動作しないとなると、お手上げです。お使いのテーマのソースを見てみないと原因は特定しづらいです。

      もし、動作するのであれば、一つずつプラグインを有効化していき、どのプラグインを有効化した時に Head Cleaner が動作しなくなるか確認してください。
      競合しているプラグインが確認できたら、プラグイン名と配布元のURLを連絡いただければ対処できるかもしれません。

      返信
      1. hbirds

        すみませんでした!
        プラグインの競合ではなく、私がTopページのみget_header() を消してして、代わりにheader.phpの中身を貼り付けていたのが原因でした。
        今は、そんないい加減なことをせずに、header.phpをページによって分岐するようにプログラムして、get_header() を復活させています。
        もちろん、Head Cleanerもばっちり動いています。
        ホント、お恥ずかしい限りです。失礼しました。

        返信
        1. をかもと 投稿作成者

          hbirds さん、どもです。
          解決されたようで良かったです。
          get_header() を呼ばれたタイミングで動作するので、get_header() が無いと動作しません。
          そのうち、FAQを作りますね。

          返信
  4. ピンバック: Telmina ? » 【WordPress】「Head Cleaner」導入奮闘記

  5. ピンバック: だい亜りー

  6. をかもと 投稿作成者

    ゆりこさん、どもです。

    正確には

    ヘッダ: get_header をフックして ob_start() し、wp_head をフック (プライオリティ 100000) して、ob_end_flush()
    フッタ: wp_footer をフック (プライオリティ 1) して ob_start() し、wp_footer をフック (プライオリティ 100000) して、ob_end_flush()

    しています。

    なので wp_footer() が無いテーマの場合は、何もしません。
    … が、ご指摘どおり wp_head() が無いテーマの場合は ob_start() が終了しません。
    wp_head() が無いようなテーマでは、そもそも他のプラグインが CSS なり、JavaScript なりを突っ込むこともないので、このプラグイン自体不要だと思うんですよ。

    ただし、wp_head() の中で ob_start() を動かすようなプラグイン (Comennt Quick Tags http://tekapo.com/st/2007/05/30/comment-quicktags-reloaded/ ) なんかとは、競合して正常に動作しません。
    まぁ wp_head をフックして ob_start() するようなプラグインがあれば、プライオリティを 100000 以降に変更してもらえば、何とかなるので良いかなと。
    この辺は、正式リリース時に FAQ を用意しようと思ってます。

    返信
  7. ゆりこ

    header.php の <?php wp_head(); ?> が呼ばれた時点でバッファ取得を終了し、書き出された文字列を解析して整形します。

    あれ? そうすると、wp_head() がないような (凶悪な) テーマだと、ob_start() が終了しないのでやばいですね。さすがに wp_head() はどのテーマもあると思いますし、なかったら、このプラグインは無用の存在なわけですが 😉

    wp_footer() がないテーマは時々あります。その場合は、なんとか動作すると思われますが、要確認ですね。

    返信

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください