本文へ移動
Column コラム

Xserverのキャッシュ機能でbaserCMS5高速化を試みる!Google Speed Insghtの点数をアップさせたい!

baserCMS5はCakePHPをベースに作られた国産CMSです。世界的なフレームワークを土台としおり、拡張性にすぐれセキュリティ面でもCakePHPの機能を利用できるため安心して機能拡張することができます。 今回はそんなbaserCMS5を一般的なレンタルサーバーの代表格「XServer」で使う際にすべき、高速化のノウハウをご紹介します。

Google Speed Insght対策を中心に

クライアントワークでサイト制作をする際に、Google Speed Insghtの話題が出ることも少なくありません。最近では単純なSEO目的というだけでなく、ユーザービリティへの配慮という意味合いも強くなってきており、対応を迫られる制作会社さんも多いと思います。 今回はXserver限定ではありますが、いくつかのテクニックをご紹介しますので、是非参考にしてみてください。

何故か効かないXserverの”ブラウザキャッシュ設定”

Google Speed Insghtで計測していると、Xserverのコントロールパネルから設定できる”ブラウザキャッシュ設定”が、baserCMS5で効かないことが分かると思います。 XServerの公式なマニュアルによると「7日間」のキャッシュ設定が入るはずですが、Chromeの開発ツールで確認すると86400秒(1日)になってしまうのです。そのため、180日〜のキャッシュ設定を求めるGoogleSpeedInsghtにおいては指摘事項として指摘があがってきてしまいます。 この状況はXserverのマニュアルに従って.htaccessを編集してExpiresActiveをONにしても変わりません。

原因は簡単で、フレームワークであるCakePHP5の設定項目に「CacheTime」という設定があり、フレームワーク側でXserverや.htaccessの設定を上書きしてしまっているためです。 しかし幸いなことに、この設定はbaserCMSの設定ファイルで上書きできます。

まず「/config/app.php」を開いてください。92行目付近に以下のような記述がありコメントアウトされていると思います。

    'Asset' => [
        //'timestamp' => true,
        //'cacheTime' => '+1 year'
    ],

これの「cacheTime」のコメントアウトを外して下さい。

    'Asset' => [
        //'timestamp' => true,
        'cacheTime' => '+1 year'
    ],

するとCakePHP5のデフォルト設定(1日)が上書きされ、1年間のキャッシュ有効期間になります。これによって、静的ファイルのキャッシュ時間がのびGoogleSpeedInsghtの評価も上がります。 ちなみにCSSやJSを更新する際には、このキャッシュ期間が仇となることがあるので、「xxxxx.css?20260501」のようにパラメータをつけるなど工夫が必要です。

肥大化する/tmp/sessionsのセッションファイル

サイトの公開直後は問題ないのですが、それなりにアクセス数があるサイトでは数万個に及ぶセッションファイルがbaserCMSの速度を落とす原因になることがあるようです(これは前バージョン4のときから同様の現象があるように思います)。

とはいえこのCMSは仕様的にトップページにアクセスしただけでもセッションファイルを作ってしまうので、セッションファイルの保持期限を明示的に短くしておくことで対応しておきます。前述の/config/app.phpの終わりの方(407行目付近)のSessionの設定項目に追記して以下のようにしておきます。

'Session' => [
    'defaults' => 'php',
    'timeout' => 120,
    'ini' => [
        'session.gc_maxlifetime' => 7200,
        'session.gc_probability' => 1,
        'session.gc_divisor' => 100
    ],
],

XServerの”サーバーキャッシュ設定”を有効にするための準備

Xserverでは一度表示したページをサーバー側でキャッシュして、次回のアクセス時にはキャッシュしたページを表示する機能があります。このサーバーキャッシュは強力でサイトの高速化にもってこいなのですが、CMSで利用するには大きな問題があります。

例えばユーザーがメールフォームにアクセスすると、不正送信防止のためのトークンがHTML内に自動出力されます。CMSはフォームの送信時にその値を確認し、間違っていれば「不正に改竄された」としてエラーを出します。このサーバーキャッシュでは、一度表示したページをそのままキャッシュしてしまうため、このトークンも保持してしまいます。最初のユーザーのトークンが2回目以降のアクセス時にも使われてしまいますので、正常にメールフォームを動かすことができません。

他にも、ログインユーザーの表示をキャッシュしてしまって「ようこそ◯◯さん」のような表示を誰にでも表示してしまうなどの問題も考えられますが、baserCMS5では管理画面のログイン中は「サーバーキャッシュをさせない」処理が入っていますので、管理画面へのログイン中にこの問題はおきません。

Xserverの公式マニュアルによると、URLにアクセスしたときのリクエストヘッダに「Cache-Controlに「no-cache」「no-store」「private」「must-validate」のいずれかを含む場合」もしくは「Set-Cookieを含む場合」は、サーバーキャッシュしないという仕様が明記されています。管理画面にログインしている場合はCache-Controlにこれらの値が含まれるのでキャッシュされる心配がありません。 そこでメールフォームのとき、それからログインする直前のログイン画面(ログインフォーム)でも同様のCache-Controlを出力させることにします。

おそらく、もっと簡単な方法があったり、baserCMS5自体が今後のバージョンアップで対応しそうな雰囲気があるのですが、/src/Application.php を開いて、bootstrapの中に以下のような記述を追記します。

// キャッシュ制御用のイベントリスナーを全リクエストで有効化する
// (管理画面・メールフォームなど、条件に応じて no-cache ヘッダを付与)
EventManager::instance()->on(new AppControllerEventListener());

結果的に下記のようになると思います。

public function bootstrap(): void
{
    // Call parent to load bootstrap from files.
    parent::bootstrap();

    // キャッシュ制御用のイベントリスナーを全リクエストで有効化する
    // (管理画面・メールフォームなど、条件に応じて no-cache ヘッダを付与)
    EventManager::instance()->on(new AppControllerEventListener());

    if (PHP_SAPI !== 'cli') {
        FactoryLocator::add(
            'Table',
            (new TableLocator())->allowFallbackClass(false)
        );
    }
}

そのまま今度は /src/Event/AppControllerEventListener.php を作成して、以下のように記述します。

 'beforeRender',
        ];
    }

    /**
     * 画面を表示する直前に呼ばれるメソッドです。
     *
     * やっていることは次の3つです。
     * 1. 相手が本当に Controller か確認する
     * 2. キャッシュを止めるべきページか判定する
     * 3. 必要なら no-cache ヘッダをレスポンスにセットする
     */
    public function beforeRender(EventInterface $event): void
    {
        $controller = $event->getSubject();
        // まれに想定外の相手が来ることがあるので、安全のためチェックします。
        if (!$controller instanceof Controller) {
            return;
        }

        $request = $controller->getRequest();
        // 「このページはキャッシュを止める必要がある?」を判定します。
        if (!$this->shouldDisableCache($request)) {
            return;
        }

        // キャッシュしないヘッダ(Cache-Control: no-store など)を付けます。
        $controller->setResponse($controller->getResponse()->withDisabledCache());
    }

    /**
     * キャッシュを止めるかどうかを決めるメソッドです。
     *
     * true  を返す  = キャッシュを止める
     * false を返す  = キャッシュを止めない
     */
    private function shouldDisableCache(ServerRequest $request): bool
    {
        // 1) ログイン中は安全のため常にキャッシュを止める
        if (BcUtil::loginUser()) {
            return true;
        }

        // 2) ルーティング情報から、どのプラグイン/画面かを調べる
        $plugin = (string)$request->getParam('plugin');
        $controller = (string)$request->getParam('controller');
        $action = (string)$request->getParam('action');

        // メールフォームの主要画面(入力/確認/送信/完了)はキャッシュを止める
        if ($plugin === 'BcMail' && $controller === 'Mail' && in_array($action, ['index', 'confirm', 'submit', 'thanks'], true)) {
            return true;
        }

        // URLパス(例: /contact/index)を取り出す
        $path = '/' . ltrim($request->getPath(), '/');

        // 3) 管理画面(/baser/admin...)は、ログイン前の画面も含めてキャッシュを止める
        if ($path === '/baser/admin' || str_starts_with($path, '/baser/admin/')) {
            return true;
        }

        // 4) 問い合わせ系のURL配下はすべてキャッシュを止める
        foreach (['/contact_01/', '/contact_02/', '/contact_03/'] as $prefix) {
            if (str_starts_with($path, $prefix)) {
                return true;
            }
        }

        // 上の条件に当てはまらないページはキャッシュを止めない
        return false;
    }
}

「/contact_01/」「/contact_02/」「/contact_03/」の箇所は、使っているメールフォームのURLを入れればOKです(メールフォームの主要画面であることを確認する部分だけでいける気もする)。

この状態で、ログイン画面やメールフォーム配下のURLを開いてCache-Controlの値が以下の画像のようになっていれば成功です。XServerのサーバーキャッシュを利用できます。

スクリーンショット 2026-05-04 19.01.14.png

Xアクセラレータを有効にする

前述のブラウザキャッシュを有効にした段階で、自動的にXアクセラレータが有効になるようです。Web上の情報をさらっていくと、この手のサーバー設定でインストール時にコケることがあるなどの情報も見えたりしますが、インストール後の動作に関して言えば問題ないようです。 Xアクセラレータには、Ver.1とVer.2とがありますが、どちらでも動作します。

JavaScriptの読み込みに「defer」を付ける

baserCMS5のJS呼び出しの関数をそのまま使っていると出てこないのですが、GoogleSpeedInsghtの値を良くするためにJSの呼び出しに「defer」や「async」をつけることがあります。 両者の違いは詳細なサイトが多数ありますのでそちらに譲るとして、$this->BcBaser->js()をそのまま使うと出てこないと思いますので、scriptタグを書くなどの対応が必要です。

また同様にGoogleタグマネージャーやAnalyticsの計測タグもGoogleSpeedInsghtの値を下げる要因になります。アナリティクスはbaserCMSで出力させることも出来たかなと思いますが、遅延処理を入れるのであればscriptタグを記述すると良さそうです。下記に遅延処理の例を示しておきます。

    

その他、XserverやbaserCMS5とは関係ないところ

その他、CMSに限らずですが、画像が必要以上のサイズになっていたり、Webフォントの利用によってレイアウトシフトが発生するなどすると、実際の体感速度は別としてGoogleSpeedInsghtの数字は悪くなります。 もちろん、GoogleSpeedInsghtが全てではないので、必要があってどうしようもないことがあると思います。その場合は「このWebサイトに求められる成果とはなにか」を考えて、より重要なものを取れば良さそうです。

まとめ

いかがだったでしょうか? baserCMSもXserverも今後の仕様変更などあるかも知れませんが、2026年5月時点では上のように設定できました。皆様の参考になれば幸いです。

ヒニアラタ編集部 監修: 馬庭 吾以千

ヒニアラタ編集部では地方の中小企業様のWeb活用をお手伝いするため、私たちが持っている専門知識を「コラム」という形で分かりやすく公開しています。 私たち自身が地方の企業であるからこそ分かること、感じることがあると思っています。

一覧に戻る