archivesの画像をData URIに変換

HTTPリクエストを減らそう運動モジュール

HTTPリクエストを減らすための手段として、ちょっと着目していたのがData URI(データスキーム)という方法。Data URIは、画像や音声などの色々なファイルをbase64エンコードを通して文字列(URI)に変換する技術です。技術のある人が極まると、えらいことできるらしいですが、今回は画像ファイルとHTMLを一体化させるために使います。

ACMS_GET_Plugin_DataUri(仮)

<?php
require_once ACMS_LIB_DIR.'GET.php';

class ACMS_GET_Plugin_DataUri extends ACMS_GET
{
    function get()
    {
        // 変換対象を正規表現パターンで定義
        $regex  = '@<img.*?src="(/'.DIR_OFFSET.ARCHIVES_DIR.'.*?|/'.DIR_OFFSET.THEMES_DIR.'.*?)"@';

        preg_match_all($regex, $this->tpl, $matches);

        if ( empty($matches[1]) ) return $this->tpl;

        foreach ( $matches[1] as $src ) {
            // 拡張子を取得
            $ext    = pathinfo($src, PATHINFO_EXTENSION);
            // ファイル取得後、base64エンコード
            $pair[$src]  = 'data:image/'.$ext.';base64,'.base64_encode(file_get_contents(DOCUMENT_ROOT.$src));
        }

        $pair   = array_unique($pair);
        $raw    = array_keys($pair);
        $data   = array_values($pair);

        //ズバっと置き換え
        $this->tpl  = str_replace($raw, $data, $this->tpl);

        return $this->tpl;
    }
}
?>

このソースコードを、DataUri.phpとして、/php/ACMS/GET/Plugin/内に配置します。アップデートとかには一切対応しないワンタイムモジュールですが、興味のある方はどうぞ。

今回は、%{ARCHIVES_DIR}{path}のような、archivesディレクトリからの参照が確実である画像ファイルパスを対象にして、いい加減に正規表現マッチングをしています。

画像のHTTPリクエストが減る

ウェブページを表示する中で、HTTP通信の時間的コストはかなり高いです。Data URIとして、画像がHTMLの中に文字列として混ざることで、HTTP通信のコストが減少します。細かいファイルをチマチマと個別で読み込むのは想像以上に読み込み時間を食い散らかしています。

a-blog cmsの場合はHTMLと一緒に、キャッシュもバッチリされてしまいますが、そこまで大きな問題にはならないはず。サイトのページ数によってはDBのcacheテーブルの内容積がモリモリ増えてしまいそうですけど。DBの容量に自信がなかったり、サイトのページ数に自信がある場合は要注意です。

肝心の使い方は

以下、plainやvicuna等、index.htmlのテンプレート1枚で完結しているようなテーマを対象にした説明です。

当ハブろぐの場合は、既存のindex.htmlをindex_raw.htmlにリネームし、新しいindex.htmlとして下記のようなテンプレートを作成しました。

<!-- BEGIN_MODULE Plugin_DataUri -->
<!--#include file="index_raw.html" -->
<!-- END_MODULE Plugin_DataUri -->

元のindex_raw.htmlの出力結果を、最後の最後でDataUriモジュールのフィルターにかけているという感じです。対象にできるimgパスがあれば、片っ端からData URIの文字列に置き換えていきます。

変換された画像は下のようなコードに変換されます。下のコードは、サブカラムの鳥さんの写真の場合です。…連続の英数字なのでハミ出ますが気にしない。

<img src="data:image/jpg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD//gA8Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcgSlBFRyB2NjIpLCBxdWFsaXR5ID0gMTAwCv/bAEMAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/bAEMBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAH4AfgMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAA(以下略!)" width="126" height="126" alt="北端のとり" id="profileImg" />

IEには元のindex_raw.htmlを使います

IEは8以降でないとData URIを表示できません。よって、ルールを使ってUser AgentからInternet Explorerには、すべて元のテンプレートである、index_raw.htmlを直接表示するように設定します。8は対応してますけど、現状のルールにはそんな器用な項目はないので全部ナシです。

そうそう滅多なことは起こらないと思いますが、なんかあったら教えてもらえると助かります。判定をもうちょっと賢くかけばもっと遊べそうですね。ちゃんと速くなるかなー?