2013年02月15日
Webサイトのパフォーマンスをチューニングする
昨今、これまで以上にWebサイト(管理画面ではなく公開側のサイト)のハイパフォーマンス向上について様々な情報を目にするようになりました。 従前のWebサイトでは、サイトのチューニングは主にサーバーサイドで取り組む課題が多かったのですが、Ajaxの普及やスマホアプリなどJavaScriptの多用によって、クライアントサイドの高速化やHTMLソース上の工夫等による高速化がより重要になってきました。
そこで、今回はMT/PowerCMSの設定やテンプレート、プラグインによってWebサイトを高速化するためのTipsについてまとめてみます。
Minifierプラグイン
Minifierプラグインは、HTML, JavaScript, CSSコードの圧縮、画像のExif情報の削除、コンテンツのgzip圧縮等の機能を提供するプラグインです。
コードを圧縮する3つのブロックタグ
- HTMLコードを圧縮 : <MTHTMLCompressor>〜</MTHTMLCompressor>
- CSSコードを圧縮 : <MTCSSCompressor>〜</MTCSSCompressor>
- JavaScriptコードを圧縮 : <MTJSCompressor>〜</MTJSCompressor>
これらのタグで囲まれた内容について、不要な空白や空行を削除したりしてコードの容量を圧縮することができます。
- 2月17日追記
MTCSSCompressor に flatten_css_imports モディファイアを追加しました。@import でインポートしているCSSをマージして1ファイル中に展開します。
<MTCSSCompressor flatten_css_imports="1"> @import "component.css"; /*ファイルを読み込んでテンプレート中に展開します*/ </MTCSSCompressor>
コンテンツのgzip圧縮
gzip 圧縮を有効にすることで、転送量を大きく縮減することができます。
Apacheの mod_deflate モジュールが利用できるのであれば、httpd.conf または .htaccess に記述を加えるだけでコンテンツの gzip転送が実現できます。
AddOutputFilterByType DEFLATE text/html text/css application/x-javascript
mod_deflate が利用できない環境でも、mt-config.cgi に Content2gzip 1 を指定することで、テンプレートのパブリッシュの際に gzipファイルを生成することができます。対象となるコンテンツの拡張子を環境変数 Content2gzipExtensions で指定可能です(カンマ区切り)。
Content2gzip 1 Content2gzipExtensions html,js,css
この場合、httpd.conf または .htaccess で以下のように記述を追記します(Apacheの場合)。
RewriteEngine on RewriteCond %{HTTP:Accept-Encoding} gzip RewriteCond %{REQUEST_FILENAME} !\.gz$ RewriteCond %{REQUEST_FILENAME}\.gz -s RewriteRule .+ %{REQUEST_URI}.gz <files *.html.gz> AddType "text/html;charset=utf-8" .gz </files> <files *.js.gz> AddType "text/javascript;charset=utf-8" .gz </files> <files *.css.gz> AddType "text/css" .gz </files> AddEncoding x-gzip .gz
DynamicMTML(ダイナミックパブリッシング)が有効な環境では、mt-config.cgi に Dynamic2gzip 1 を指定することでPHPによって gzip圧縮を利用できます。
Dynamic2gzip 1
この設定によってダイナミックパブリッシングの初期化時に <?php ini_set( 'zlib.output_compression', 'On' );?> が実行されます。
画像のExif情報を削除して、容量を減らす
mt-config.cgi に RemoveExifAtUploadImage 1 を指定することで、ファイルのアップロード時にExif情報を削除してファイル容量を減らしてくれます。この環境設定はプラグインインストール時デフォルトでOnになっていますので、Offにしたい時には mt-config.cgi に下記を追記してください。
RemoveExifAtUploadImage 0
このプラグインでは、既にアップロード済みのファイルに対しては処理を行いません。そこで、プラグインに同梱されている remove-exif スクリプトを実行して、これまでに登録済みの画像に対しても同様の圧縮処理を行うことができます。スクリプトを設置してコマンドラインから以下を実装します。
$ cd /path/to/mt $ perl ./tools/remove-exif
Data URI scheme を利用してHTTPリクエストを減らす
Data URI scheme を利用すると外部データ無しにウェブページにデータを埋めこむことができます。埋め込んだ分のHTTPリクエストを減らすことで高速化が見込めますが、Data URI で埋め込む場合、データをBase64でエンコードする必要があるため、転送されるデータ量は約3割ほど増加します。
Asset2Base64プラグイン
このプラグインが有効な環境では、ファイルのパスに convert2base64 モディファイアを追加することでデータをBase64でエンコードして出力することができます。 ファイルのパスは <$MTAssetFilePath$> タグで取得できますが、Movable Typeにはサムネイルのパスを取得するMTタグがありません。そこで、このプラグインは <$MTAssetThumbnailFile$> テンプレートタグを提供します。
<img src="data:<mt:AssetMimeType>;base64,<mt:AssetFilePath convert2base64="1">" width="<mt:AssetProperty property="image_width"$>" height="<mt:AssetProperty property="image_height"$>" alt="<mt:AssetLabel escape="html">" />
Data URI が一般的に利用されてこなかった理由の一つに Internet Explorer 7までサポートされておらず、Internet Explorer 8でもデータサイズが32 KBに制限されていることがあげられます。
下記のテンプレートは、Base64エンコードした文字列の容量が 32 KB未満の場合にのみ Data URI に変換します。get_content_length モディファイアもAsset2Base64プラグインによって提供されます。
<mt:Asset id="1"> <mt:AssetThumbnailFile width="32" square="1" convert2base64="1" setvar="src"> <mt:Var name="src" get_content_length="1" setvar="image_size"> <mt:If name="image_size" lt="32768"> <img src="data:<mt:AssetMimeType>;base64,<mt:Var name="src">" width="32" height="32" alt="<mt:AssetLabel escape="html">" /> <mt:else> <img src="<mt:AssetThumbnailURL>" width="32" height="32" alt="<mt:AssetLabel escape="html">" /> </mt:If> </mt:Asset>
MTIfIE プラグインを使えば、DynamicMTMLで動的にブラウザを判別して分岐させることもできます。
DynamicMTML(ダイナミックパブリッシング)のパフォーマンスを向上させる
DynamicMTMLを有効にしている場合、PHPによる各種処理やデータベースアクセスの負荷を軽減することで、パフォーマンスを改善することができます。
キャッシュと条件付きGET
ウェブサイト/ブログの全般設定画面で、キャッシュ(ファイルキャッシュ)と条件付きGETにチェックを入れることで有効化されます(「キャッシュする」と「ビルド結果をキャッシュする」の違いは、後者はパラメータ付きリクエストを別々にキャッシュする点です)。条件付きGETが有効な場合、ファイルの更新日を見て更新がない場合はブラウザキャッシュを利用させるHTTPヘッダを返します(ファイルの更新日を見るため、インクルードファイルの更新などが考慮されない点に注意してください)。
DynamicCacheSQLiteプラグイン
ファイルキャッシュの代わりにSQLite(SQLite2)を利用してデータをキャッシュするプラグインです。ファイルキャッシュと比較して有利な点は、コンテンツデータだけでなく、データを生成するためのSQLの実行結果などもキャッシュすることができ、そもそものパフォーマンスを向上させられる点です。
mt-config.cgi に指定可能な環境変数と初期値は以下です。
DynamicCacheSQLite /path/to/DynamicMTML.sqlite # データベースファイルへのパス DynamicCacheLifeTime 14400 # キャッシュの有効時間 DynamicCacheFileInfo 1 # fileinfoオブジェクトをキャッシュ DynamicCacheBlog 1 # blogオブジェクトをキャッシュ DynamicCacheArchiveObjects 0 # entryやcategoryオブジェクトをキャッシュ DynamicCacheArchiveObjectLifeTime 7200 # entryやcategoryオブジェクトをキャッシュの有効秒 DynamicCacheConditional 1 # 条件付きGETを有効にする DynamicCacheContent 1 # コンテンツをキャッシュする DynamicCacheContentLifeTime 3600 # コンテンツキャッシュの有効秒 DynamicCacheIfNonMatchFI index.html # /で終わるリクエストで対象にするファイル名 DynamicCacheVacuumPeriod 0 # 定期的にVacuumコマンドを実行する DynamicCacheVacuumCheckFile /path/to/CheckFile # Vacuumコマンド実行間隔を見るためのファイル
マルチデバイス対応などで同一URLで違う結果を返す場合のキャッシュ設定
「ビルド結果をキャッシュする」設定を有効にした場合、DynamicMTMLのマルチデバイス機能を使ってデバイス毎に違うHTMLを生成している場合に、単一のデバイス用ののHTMLがキャッシュされてしまうことになります。これを回避する方法は2つあります。
1つは、アクセスするURLにパラメタを付与する方法(例:スマホの場合?sp=1を付与してアクセスさせる)。もう一点はプラグインを利用する方法です。
MultiDeviceCacheプラグイン
mt-config.cgi に指定可能な環境変数と初期値は以下です。
EnableMultiDeviceCachePC 1 # PC用キャッシュを利用 EnableMultiDeviceCacheSP 1 # スマホ用キャッシュを利用 EnableMultiDeviceCacheFP 0 # フィーチャーフォン用キャッシュを利用 MultiDeviceCacheTabletIsPC 1 # Tablet端末のキャッシュとPC向けキャッシュを共用 MultiDeviceCacheDir multidevicecache # キャッシュディレクトリ名
DynamicMTMLの初期化高速化については、下記の記事も参考にしてください。特にPHPアクセラレータの利用や不要なプラグインの削除は効果的です。
管理画面用のJavaScript/CSSの圧縮によるパフォーマンスの向上
最後に(これは公開側のサイトが対象ではないのですが)、MTの管理画面用の JavaScript/CSS コードを圧縮する機能について紹介します(方法は2つあります)。この機能はMinifierプラグインによって提供されます。
PHPによる動的なコード圧縮
Minifierプラグインのパッケージ含まれる mt-static/minify_2 ディレクトリをサーバーにアップロードします。 「設定」メニュー→「全般設定」の「mt-static以下のJavaScript / CSSコードを圧縮する」にチェックを入れて、設定を保存します。 mt-static以下に .htaccessが生成され、minify(http://code.google.com/p/minify/)によって JavaScript/CSS コードが圧縮されてブラウザに送信されるようになります。
スクリプトによってファイル中のコードを圧縮
Minifierプラグインのパッケージ含まれる tools/mt-static-minifier をサーバーにアップロードします。コマンドラインから以下を実行してください(事前にバックアップをお願いします)。
$ cd /path/to/mt $ perl ./tools/mt-static-minifier
コメントを投稿する