先日のサーバ移行にあわせて配信まわりを見直した結果、記事ページの転送量がgzip圧縮後で約70KB減りました。計測に使った記事では115KBが42KBになり、63%の減少です。一番効いたのは、何かを足すことではなく、テーマの「CSS縮小化」という高速化のための設定を切ったことです。
きっかけは、Claude Codeへ「記事ページが重い原因を、要素ごとに分解して調べて」と頼んだことでした。返ってきた数字は予想外で、817KBの記事ページのうち、1つの<style>タグだけで671,834バイトと、ページの84%を占めていました。
前回のインフラ編で1行だけ触れた話を、詳しく書きます。

ページを要素ごとに集計したら84%がCSSだった
「なんとなく重いな」と感じるだけで放置していたページを、要素ごとに分解して集計させました。
| 記事ページの構成(raw 817KB) | サイズ | 割合 |
|---|---|---|
インライン<style> | 671,912 B | 84.0% |
インライン<svg> | 3,793 B | 0.5% |
<script> | 6,089 B | 0.8% |
| 本文ほか | 残り | 14.7% |
<style>の冒頭は.wp-block-accordion{...}。WordPressのブロックCSSが、外部ファイルではなくHTMLに直接埋め込まれています。中身を調べると、サイトに登録されている116種類のブロックすべてのCSSが入っていました。このページが実際に使っているブロックは7種類なので、残る109種類分はこのページでは一度も使われません。
gzipで圧縮しても、このCSSだけで88KB。転送量の77%を占めていました。
原因はCocoonの「CSS縮小化」だった
埋め込んでいたのは、テーマ(Cocoon)の高速化設定「CSS縮小化」(内部名css_minify_enable)でした。この機能はサイト内のCSSを結合・縮小したうえで、外部ファイルではなくインラインで出力します。
116種類のブロックすべてが入っていた理由も、この機能にありました。WordPressには、使用中のブロックのCSSだけを読み込む仕組み(should_load_separate_core_block_assets)があります。ところがCocoonは、CSS縮小化と競合するためにこの仕組みを無効にしていました。結果として、この設定ひとつで「全ブロックのCSSが」「毎ページに」「キャッシュ不可能な形で」埋め込まれていたことになります。
縮小(minify)自体は正しい処理です。問題はインライン出力の方でした。外部ファイルなら初回に1度ダウンロードされてブラウザにキャッシュされるものが、インラインでは全ページ・全訪問で毎回転送されます。数KBのCSSなら リクエスト数を減らせるぶん得ですが、671KBでは完全に逆効果です。
「ブロック個別読み込み」は13%しか効かなかった
直し方は2通り考えられます。使うブロックのCSSだけに絞るか、CSSを外部ファイルに戻してキャッシュさせるか。まず前者を実験させました。
| 現状 | ブロック個別読み込み | |
|---|---|---|
| HTML(gzip後) | 115,194 B | 100,235 B(-13%) |
| ブロック定義 | 116種 | 30種 |
| 外部CSS | 0本 | 0本 |
使うブロックだけに絞っても13%しか縮みません。重かった原因は、定義が多いことではなく、キャッシュが効かない形で毎回転送されることだったからです。方針は外部ファイル化に決めました。
切った結果
CSS縮小化を無効にすると、CSSは12本の外部ファイルに戻りました。
| 縮小化ON | 縮小化OFF | |
|---|---|---|
| HTML(raw) | 816,909 B | 415,500 B |
| HTML(gzip後) | 115,178 B | 47,019 B |
| インラインCSS | 671,882 B | 266,306 B |
外部CSS <link> | 0本 | 12本(gzip後 計78KB) |
この78KBの内訳は、Cocoon本体と同梱ライブラリが9ファイル(59KB)、WordPress本体のブロックCSSが1ファイル(19KB)、プラグインが2ファイル(1KB)で、ほぼテーマのCSSです。つまり初回訪問の総転送量は約120KBで、実は以前とほぼ変わりません。
それでも初回から速くなる余地はあります。外部ファイルはHTTP/2で並列にダウンロードされるので、115KBのHTMLを1本の流れで受け取り終えるのを待つより、42KBのHTMLと並列のCSSの方が表示を始めやすいからです。そして、はっきり効くのは2ページ目からです。CSSはブラウザとCloudFrontにキャッシュされて再転送されなくなり、以降は1ページ42KBで済みます。表示崩れがないことは、切り替え前後のレンダリング比較で確認してから反映しました。
ついでに見つかった397KB
計測の副産物がもう1つありました。数式表示ライブラリのMathJax(本体274KB+音声読み上げ用123KB=397KB)が、数式のないトップページを含む全ページで読み込まれていたのです。プラグイン(simple-mathjax)のコードを読ませると、条件判定を持たず、どのページでも読み込む作りになっていました。
このブログで数式を含む公開記事は1本だけです。本文に$$や\(があるときだけ読み込む小さなプラグインを作って、その1本では今までどおり数式が表示されることを確認しました。残りすべてのページから397KBが消えます。
ここまでで、計測に使った記事はgzip後42KB。元の115KBから3分の1になりました。なお広告スクリプトの重さは残っていますが、これは収益との交換なので、そのままにしています。
教訓:高速化設定は効果を測ってから使う
「CSS縮小化」という名前だけ見れば、有効にしない理由がありません。私も何年も有効のまま使っていました。それが実際には、ページの84%を占める重りになっていた。設定画面の名前は効果を保証しません。
今回の手順はどれも単純です。ページを要素ごとに集計する、疑わしい設定をOFFにして同じ計測を繰り返す、差分を見る。手でやると面倒なこの往復が、AIに頼むと数分で回ります。高速化プラグインや設定を入れる前に、まず自分のページを数えてみることをおすすめします。
おまけ:この修正で、WordPressが描画する404ページも875KBから319KBに縮みました。それでもまだ重いこのページが、なぜ問題なのかは次の記事で書きます。



コメント