CSS や javascript の縮小&結合の一発処理を独自作成
今、使っている WordPress テーマ Simplicity は
結構な数の CSS をimport してるので、これを 縮小 & 結合することにした。
(ついでに、javascript も)
ちなみに、世間的には「圧縮」とか言うこともあるけど、
圧縮って Gzip にすることやろ?
正確には「最適化」とか「縮小」だと思うw
プラグインとかライブラリは使わない
便利な世の中になったもんで、
Wordpress なら、こういった処理を
勝手にやってくれるプラグインとか、たくさんある
なので、おいらも試してみた。
色々と弊害があるのでプラグインは使わんことにした
WordPress なら有名どころで、
Head Cleaner とか Autoptimize とかあって、
自動的に CSS や javascript を最適化して結合してくれる。
でも、動的だったり、膨大にキャッシュしたり、
どうにも弊害が多い。
おいらは、静的に最適化したいのでござる (・ω・`)
手動ならば、Online JavaScript/CSS Compressor
なんてものもあるんだけど、CSS に手を加えるたびに
いちいち手動でなんかやってられんwww
だったら、独自に作成するしかない
php のライブラリも使わないことにしたw
独自に作成するなら php のライブラリ使えば簡単だよね。
有名どころで、YUI Compressor を利用してみた。
でも、なんか・・・
おいらが期待してる動作をしてくれなかった・・・
2015/01/19 追記:
最新バージョンで思った通りの動作をしてくれたので
YUI Compressor 使うことにしました(記事1、記事2)
なので、
自分の環境にあったものを、自分のためだけに作る
っていう方針にしたw
作ってみる
とりあえず、処理の流れ
- WordPress で使用してるテーマディレクトリ内を走査して
.css ファイル(.min.css 除く)を再帰的に見つけ出して縮小。
.min.css の拡張子で保存する。 - css ファイル内で import されてるものがあったら
それを親ファイルに結合。 - 外部 CSS を結合。
- 再び、テーマディレクトリ内を走査して .js ファイル(.min.js 除く)を縮小。
.min.js の拡張子で保存する
javascript は、下手に結合すると何が起きるか分からんので、
とりあえず、縮小するだけにとどめた。
CSS の縮小
処理1 の .css ファイルの縮小は、結構簡単。
たぶん、以下の正規表現でいけると思う(たぶん)。
$css = preg_replace( array('{\t|\r|\n}', '{(/\*(.*?)\*/)}'), "", $css);
$css = preg_replace( array('{([\(|\[])\s*}', '{\s*([\)|\]])}'), '$1', $css );
$css = preg_replace( "/\s*([\{|\}|:|;|'|\"|,])\s*/", '$1', $css );
$css = preg_replace( "/\s+/", " ", $css );
import されてる CSS を親に結合
処理2 の import されてる .css ファイルの結合も、比較的簡単
@import の url 部分だけ抜き出して
@charset と @import を消す。
preg_match_all( "/@import[^;]*url\s*\((.+?)\)[^;]*;/i", $css, $import_array );
$css = preg_replace( "/@charset[^;]+\;/i", "", $css );
$css = preg_replace( "/@import[^;]*url\s*\(.+?\)[^;]*;/i", "", $css );
あとは、抜き出した($import_array に入れた)パスの CSS を結合するだけ。
この時、CSS の解釈優先順位的に import されてるものが上に記述されるようにしないといかん。
本当は @charset に合わせてエンコードしないといかんのだが、
自分の環境で、別々の charset なんてあり得ないからやめたw
外部 CSS を結合
これは、ちょっと面倒くさい。
CSS が格納されたディレクトリが別々の場合。
background 等のパスの記述が
background: url(img/ahoaho.png);
だったり、
background: url('./ahoaho.png');
だったり、
background: url("../../img/ahoaho.png");
だったり、
パスがバラバラだから。
なので、この url を全て /wp-content で始まるパスに変換
(http://、https:// で始まるものは除く)
ただ、特殊な部分で、base64 に変換した画像などが埋め込まれてる場合があるので、
url('data:~’);
とかで始まるものは除外する処理にした。
たぶん、これで大丈夫。
また、注意点として、import された CSS と違って、
CSS の解釈優先順位が後から読み込まれたものが優先されるので、
元ファイルの後ろに結合してやらんといかん。
こーいう部分、面倒くさいわー (´Д`)
Javascript の縮小
これ、結構やっかいな気がする (・ω・`)
とりあえず、自分環境で動けばいいので、
以下の正規表現で、テキトーに縮小した・・・
// コメント削除
$js = preg_replace( "/([\{|\}|;|'|\"|,])\s*?\/\/.+?\n/", "$1\n", $js );
$js = preg_replace( "/\n[\s|\t]*?\/\/.+?\n/", "\n", $js );
$js = preg_replace( array('{\n\/\/.+}','{\A\/\/.+}'), "", $js );
$js = preg_replace( "/\/\*(.*?)\*\//s", "", $js);
// 消しても大丈夫そうな改行とか空白削除
$js = preg_replace( "/\s*([\+|\-|=|\:|;|,])\s*/", '$1', $js );
$js = preg_replace( array('{\n\s+}','{\A\n}'), "", $js );
$js = preg_replace( "/\r*\n*([\{|\}|\(|\)])\r*\n*/", '$1', $js );
2015/01/19 追記:
動作しない Javascript があったので、ちょこっと修正しました
2015/01/21 追記:
動作しない Javascript があったので、ライブラリ使うことにしました(記事2) orz
今のところ、おいらの環境では大丈夫だけど、
他の javascript が全部、これで OK なのか分からん。
もっとキレイで安全なコードがあったら、誰か教えてください・・・
今回やらなかったこと
プラグインで自動的に挿入される CSS や javascript は
静的に保存して良いのか分からんものが多いので、無視することにした。
最適化した結果
ボタン一発で、縮小・結合できるようになったので、
Wordpress テーマの head 内の CSS を style.min.css だけにして、
実際に動かしてみた。
head 内が style.min.css だけになってスッキリ ヽ(´ー`)ノ
PageSpeed Insights
PageSpeed Insights の結果。
・ PC
・ モバイル
PC で 3点アップ。モバイルで7点アップw
まぁ、微々たるものだね。
体感速度
体感速度に関しては、変化なんてあるわけがないw
もともとの CSS ファイルの総サイズが 113.7KB
最適化後の CSS ファイルのサイズは、84.1KB
29.6 KB しか削減できてないw
そもそも、Gzip で圧縮してやれば、最適化せずとも
113.7KB → 24.3KB になる。
Gzip での圧縮なら 89.4KB 削減できるもんw
まぁ、最適化 & 圧縮であれば、
113.7KB → 17.6 KB になるので、約7分の1
悪くはない。
だが、重要なのは、最適化より、やっぱり圧縮だと思うw
ディスカッション
コメント一覧
Googleしてここに来ました。
InsightsでEliminate render-blocking JavaScript and CSS in above-the-fold contentで怒られたためです。
が…予想通りそんなスコア上がらないんですね。CSSやJavascriptに掛かるコスト考えると当たり前ですが(笑)
やる価値はないとは言わないですが、労多くして功少なしのような感じがします。
プラグインは便利ですが、やっぱり面倒ですね。
突然ですがはじめまして。ワードプレスにてサイト運営しているよくできる?学生です。
私もサイトの高速化には悩んでいるので、この記事で紹介されているCSS や javascript の縮小&結合をぜひやってみたいと思います。
ところが、このいくつかページで紹介されているコードの使い方がよく分かりません。
functions.phpに書けばいいのか、cssやjsにそのまま(まさかとは思いますが)かくのか・・・
忙しい中申し訳ありませんが教えていただければと思います。
yokudekiru さん。
記事内に書かれているリンク先で、
記事1 には、YUI Compressor で CSS を圧縮するソース
記事2には、jsmin-php で Javascript を圧縮するソース
をそれぞれ書いておりますので、そちらを参照していだけますでしょうか。
返信遅れてすいません。
記事1・記事2、ともにに読ませていただきました。
前は、コードの意味も半分くらいしか理解できなかったのですが、いまはだいぶ勉強したおかけで、ほとんどの意味がわかったので、とても参考になりました。
当初は私の作っているH Speed WPというワードプレスプラグインにcssやjsの圧縮機能を導入してみたいなと思ったのですが、やっぱりどのテーマにおいても、機能するようにするのは私の力では無理そうです。
あと、WpTHKというテーマ以前にも見させてもらったのですが、いつの間にかすごく進化していて本当にすごいです。私のプラグインで設定項目が100ほどあって、多いと思っていたのですが、WpTHK見てたらすごく少なく見えてしまいました。
受験勉強もそろそろ本格的にはじめないといけないので、できるか分かりませんが、時間があればぜひWpTHK使わせていただきたいと思います。
> cssやjsの圧縮機能を導入してみたいなと思ったのですが、
Autoptimize というプラグインは CSS・Javascript の圧縮するプラグインですが、いろいろな所で不具合が出てるようですね。
どんなテーマにも対応させるというならば、
・CSS と Javascript の中を解析して、パスを通さないといけない。
・動的に圧縮するか、静的に圧縮してキャッシュしないといけない。
でも、動的に圧縮するとサーバーに負荷がかかる。
静的に圧縮してキャッシュすると、レスポンシブへの対応ができなかったり、いろいろ不具合が出る。
パスを通すにも、絶対パスに変換するのが簡単だけど、
せっかく圧縮しても、むしろサイズがデカくなる可能性すらある。
これらの理由で、どんなテーマにも対応させるというのは、かなり難しい気がします。
WpTHK テーマは、カスタマイズした内容を CSS に書き込んで自動的に圧縮したり、
ユーザーが書いた子テーマの CSS・Javascript を圧縮して静的に保存する機能がついてますが、
プラグインではなくテーマだから可能な機能と言えますね。
—
受験勉強がんばってね(高校受験かな?)。
おいら、大学受験時代が楽しかったので、受験生大好きやねんw