外部CSSを勝手に結合してMinify!

#acmscamp 最終日の成果発表のこと

強化合宿の初日に、外部CSSの結合をシステム側でやってもらえないか、とかいう話をどなたから頂きました。そんで、参加者の皆様のサポートをしながら、実装の妥協点を考えつつ、2日目にコードを書いてみた次第。

下記のように記述すると、外部CSSの結合&最小化(空白・改行コード・コメントの削除)までを自動化して、最終的にページの内部スタイルシートとして読み込みます。

<!-- BEGIN_MODULE Plugin_CombineCSS -->
<link rel="stylesheet" type="text/css" href="/css/import.css" />
<link rel="stylesheet" type="text/css" href="/css/acms.css" media="all" />
<link rel="stylesheet" type="text/css" href="/css/acms4vicuna.css" />
<!-- END_MODULE Plugin_CombineCSS -->

モジュールとして実際に利用するには、下記のコードを、CombineCSS.phpとして、/php/ACMS/GET/Plugin/の中に保存してください。

<?php

require_once ACMS_LIB_DIR.'GET.php';

class ACMS_GET_Plugin_CombineCSS extends ACMS_GET
{
    function get()
    {
        if ( preg_match_all('@href="(.*?)"@', $this->tpl, $matches) )
        {
            $comb   = '';

            foreach ( $matches[1] as $path ) {

                // CSSファイルの実体を参照して保存
                $css    = PHYSICAL_PATH.$path;
                if ( !is_file($css) ) continue;
                $css    = file_get_contents($css);

                // 文字コード宣言を除去 (ほんとはテンプレートにあわせてエンコードすべき?)
                $css    = preg_replace('/@charset ".*";/', '', $css);

                // CSSをminifyな感じに変換
                $regex  = array('{\t|\r|\n}', '{(/\*(.*?)\*/)}');
                $css    = preg_replace($regex, '', $css);

                // 結合
                $comb   = $comb.$css;
            }
        }

        $comb   = '<style type="text/css">'.$comb.'</style>';

        return $comb;
    }
}

?>

初見のHTTPリクエスト自体は削減されますが、実際、CSSは適切にExpire(有効期限)を設定していればキャッシュされます。これを使ってしまうと、単一ページのファイルサイズが一律で増えてしまうため、全体転送量のチューニングとしては微妙です。入り口率の高い、ランディングページ等のファーストインプレッションに関わるページで、パフォーマンスを調整したい時には有効でしょう。

本当は、カスタムフィールドでカスタムフィールド(以下CF)を半動的生成することを考えていたのですが、余裕をもてず見送りホームラン。

予定していたのは、ブログのCFでHTML的な定義を、カテゴリーのCFでフィールド名や初期値の定義を、最後にエントリーのCFで利用、という流れ。(直感でいけそう、という程度の予定だったので、本当に実現可能かどうかは別!)余裕あるときに試してみます。もしくはどなたかチャレンジしてみてください。