外部CSSを勝手に結合してMinify!
Posted: Updated:
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で利用、という流れ。(直感でいけそう、という程度の予定だったので、本当に実現可能かどうかは別!)余裕あるときに試してみます。もしくはどなたかチャレンジしてみてください。