はじめに
「WordPress高速化」シリーズの第9回です。SWELLの高速化設定にある「ページ遷移高速化」のPrefetchは、「マウスを乗せると重い」という声を見かけます。当サイトもオンにしていたので、仕組みと効果を測ってみました。
結果は次のとおりです。
- 当サイトでは、SWELLのPrefetchと、WordPress本体の先読み機能が二重に動いていた
- SWELLのPrefetchは先読みの通信をしているのに、Chromeでは、移動するときにその結果が使われていなかった(表示の速さは先読みなしと同じ)
- 本体の先読みは使われていて、設定を1つ変えると、移動先のページの応答が約190ms→約6msになった
この記事では、SWELLのPrefetchをオフにして、WordPress本体の先読みに一本化する方法を解説します。
WordPress 7.1.4、SWELL 2.19、Chrome 156 で確認しています。SWELLの子テーマの functions.php を使います。編集する前に、必ずバックアップを取ってください。
ページの先読み(prefetch)とは
ページの先読みは、読者がリンクをクリックする前に、リンク先のページのHTMLを取っておく仕組みです。クリックしたときにはHTMLが手元にあるので、サーバーの応答を待たずに表示を始められます。
速くなるのは、記事から記事へ移動するときだけです。検索結果から最初に開いたページの表示は速くなりません。また、読者がクリックしなかったページも先読みするので、先読みが多いほど、サーバーへのリクエストと通信量が増えます。「重い」と言われるのは、この部分です。
SWELLとWordPress本体、2つの先読み
WordPressでSWELLを使っていると、先読みの仕組みが2つあります。
| SWELLのPrefetch | WordPress本体の先読み | |
|---|---|---|
| 設定場所 | SWELL設定 > 高速化 > ページ遷移高速化 | なし(WordPress 6.8から自動で有効) |
| 仕組み | JavaScriptで <link rel="prefetch"> を追加する | ブラウザの Speculation Rules という機能に、ルールを渡す |
| PCで先読みするとき | リンクにマウスが0.05秒乗ったとき(通り過ぎただけでも) | 初期設定はクリックしたとき |
| スマホで先読みするとき | 画面に入ったリンクを、1秒に3件ずつ | 初期設定はタップしたとき |

SWELLのPrefetchの動き
SWELLのスクリプト(prefetch.min.js)を読むと、PCとスマホで動きが違います。
- PC:リンクにマウスが0.05秒乗ると先読みします。記事を読みながらマウスを動かしただけでも、通り過ぎたリンクが先読みされます
- スマホ:画面に入ったリンクを順番待ちに入れ、1秒に3件ずつ先読みします。リンクに触れたときも先読みします
さらに、目次のリンク(# で始まるページ内リンク)も先読みの対象になっていて、スマホでは今読んでいるページ自体を取り直していました。
WordPress本体の先読み(Speculation Rules)
WordPress 6.8から、本体がページに <script type="speculationrules"> を出力するようになりました。ブラウザは、このルールに従って先読みします。先読みのタイミングは eagerness という値で決まります。
| eagerness | 先読みするとき |
|---|---|
| conservative(初期設定) | リンクをクリック・タップしたとき |
| moderate | PCでリンクにマウスを約0.2秒乗せたとき |
| eager | より早い段階で先読みする(通信量が増える) |
マウスのないスマホでのタイミングは、ブラウザが決めます。後の実測では、スマホの画面サイズでスクロールしただけでは、moderate でも先読みしませんでした。
本体の先読みは、パーマリンクを「基本」以外にしていて、ログインしていないときに出力されます。管理画面のURL、? の付いたURL、rel="nofollow" の付いたリンクは、最初から先読みしません。
自分のサイトで二重になっていないか確かめる
ログインしていない状態(Chromeのシークレットウィンドウなど)で記事を開き、ページのソース(Ctrl+U)で次の2つを検索します。
| 検索する文字 | 見つかったら |
|---|---|
swell_prefetch-js | SWELLのPrefetchが動いている |
speculationrules | WordPress本体の先読みが動いている |
両方見つかったら、先読みが二重に動いています。 当サイトは両方見つかり、本体は "eagerness":"conservative"(初期設定)でした。
実測1:どれくらい先読みしているか
Localで、本文にほかの記事へのリンクを20本入れたテスト記事を作り、操作ごとにサーバーに届いた先読みのリクエストを数えました。
| 操作 | SWELL | 本体(初期設定) | 本体(moderate) | SWELL+本体(moderate) |
|---|---|---|---|---|
| PC:スクロールだけ | 0 | 0 | 0 | 0 |
| PC:リンク10本の上を0.1秒ずつ通り過ぎる | 10 | 0 | 0 | 10 |
| PC:リンク5本に0.3秒ずつ止まる | 5 | 0 | 5 | 10(同じページを2回ずつ) |
| スマホ:最後までスクロール | 27 | 0 | 0 | 27 |
SWELLは、PCではマウスが通り過ぎただけで、スマホではスクロールしただけで先読みします。スマホの27件のうち3件は、目次のリンクから今のページ自体を取り直したものでした。本体の moderate は、マウスを止めたリンクだけを先読みします。
実測2:SWELLの先読みは、移動するときに使われていなかった
次に、本文のリンクにマウスを0.3秒乗せてからクリックし、移動先のページの応答が届くまでの時間(TTFB)を測りました(各3回)。
| 設定 | サーバーへのリクエスト | 移動先のTTFB |
|---|---|---|
| 先読みなし | 1回 | 約190ms |
| SWELLのみ | 2回(先読み+クリック後にもう一度) | 約190ms(先読みなしと同じ) |
| 本体(初期設定) | 1回 | 約80ms |
| 本体(moderate) | 1回 | 約6ms |
| SWELL+本体(初期設定) | 2回 | 約75ms |
SWELLのみの場合、先読みはしているのに、クリックした後に同じページをサーバーからもう一度取得していました。先読みの通信が増えるだけで、移動は速くなっていません。当サイトの本番(HTTPS)でも、先読みしたページを移動時に使わず、約75KBを取り直していました。
使われない理由
SWELLの先読み(<link rel="prefetch">)は、取得したページをブラウザのふつうのキャッシュに入れます。移動するときにそのキャッシュを使えるかどうかは、ページの応答に付いているキャッシュの指定(Cache-Control)で決まります。WordPressのHTMLには、この指定が付いていません。そのため、Chromeはキャッシュを使わず、サーバーに取り直しにいきます。
本体の先読み(Speculation Rules)は、取得したページを先読み専用の場所に保管し、移動するときにはそこから使います。キャッシュの指定がなくても使われます。

Localで試しに Cache-Control: max-age=300 を付けると、SWELLの先読みも使われ、TTFBは約8msになりました。ただし、HTMLにキャッシュの指定を付けると、記事を更新しても読者のブラウザに古いページが残るなどの副作用があります。本体の先読みに一本化するほうが安全です。
手順:本体の先読みに一本化する
Step1:SWELLのPrefetchをオフにする
SWELL設定 > 高速化 > ページ遷移高速化 の「高速化の種類」を 「使用しない」 にして保存します。
Step2:functions.phpで先読みのタイミングを変える
本体の初期設定(クリックしたとき)のままでも先読みは使われますが、マウスを乗せたときに先読みするほうが速くなります。子テーマの functions.php に、次のコードを追加します。
// ページの先読みを、リンクにマウスを少し乗せたときに行う
add_filter('wp_speculation_rules_configuration', function ($config) {
if (is_array($config)) {
$config['mode'] = 'prefetch';
$config['eagerness'] = 'moderate';
}
return $config;
});wp_speculation_rules_configuration:本体の先読みの設定を変えるフィルターですis_array($config):ログイン中など、本体が先読みを出力しないときは$configがnullになります。そのときは何も変えずに返します'mode' => 'prefetch':HTMLだけを先読みします。もう一つのprerenderは、画像やスクリプトまで読み込んで、ページを裏で表示しておく方式です'eagerness' => 'moderate':マウスを約0.2秒乗せたときに先読みします
Step3(任意):先読みしないページを追加する
問い合わせフォームのページなど、先読みさせたくないページがある場合は、次のコードを追加します。
// 先読みしないページを追加する
add_filter('wp_speculation_rules_href_exclude_paths', function ($paths) {
$paths[] = '/contact/*';
return $paths;
});/contact/* は、/contact/ で始まるURLという意味です。リンク1本だけを外したい場合は、リンク(またはそれを囲む要素)に no-prefetch というクラスを付ける方法もあります。
Step4:動作を確かめる
- ログインしていない状態で記事を開き、ページのソース(Ctrl+U)を検索する →
swell_prefetch-jsが見つからない。speculationrulesの中に"eagerness":"moderate"がある - 記事の中のリンクにマウスを少し乗せてからクリックし、移動先のページで検証ツール(F12)の「Console」タブを開いて、次のコードを実行する
performance.getEntriesByType('navigation')[0].deliveryType'navigational-prefetch' と表示されれば、先読みしたページが使われています。空('')の場合は、サーバーから取得しています。
ネットで見かける設定例は効くのか
SWELLのPrefetchについて調べると、次のような設定例が見つかります。
SWELLのPrefetchに、Flying Pagesと同じオプションを渡すコード
SWELLのPrefetchは、先読みのプラグイン「Flying Pages」とほぼ同じ処理です。そこで、Flying Pagesと同じオプション(待ち時間や1秒あたりの件数)をJavaScriptの変数で渡す、というコードです。しかし、SWELL 2.19のスクリプトが読む変数名は、こうしたコードで使われている名前とは違っていて、渡しても反映されません。紹介されている値(待ち時間0・1秒に3件・ホバー0.05秒)も、SWELLの初期値と同じです。そもそも先読みしたページが使われていないので、オプションを調整しても移動は速くなりません。
quicklink(Googleの先読みライブラリ)を入れる方法
quicklinkは、画面に入ったリンクを、ブラウザの手が空いたときに先読みするJavaScriptのライブラリです。WordPress用のプラグインもあります。本体のSpeculation Rulesとは別物で、入れると先読みの仕組みが3つ重なります。SWELLと同じく <link rel="prefetch"> で先読みする方式なので、同じ理由で使われない可能性があります。本体の先読みがあれば、追加する必要はありません。
注意点
- 対応していないブラウザでは先読みしない:Speculation Rulesは、ChromeやEdgeなどで先に使えるようになった機能です。対応していないブラウザでは先読みせず、ふつうに表示されるだけで、表示が崩れることはありません
- ログイン中は確かめられない:本体はログイン中に先読みを出力しません。シークレットウィンドウなどで確かめてください
- キャッシュを削除してから確かめる:SWELLのキャッシュやキャッシュ系のプラグインを使っている場合は、設定を変えたら削除してください
よくある質問・エラー対処
Q. Localで確かめると、本体の先読みが動きません
→ Speculation Rulesは、HTTPSのページでしか動きません。Localのサイトが http:// の場合、ソースに speculationrules は出力されますが、先読みはされません。動作は本番(HTTPS)で確かめてください。
Q. ページ遷移高速化の「Pjax」にすればいいですか
→ SWELLの設定画面でも「非推奨」と書かれています。ページを丸ごと読み込み直さない方式のため、プラグインやAdSenseの自動広告などが正しく動かないことがあります。
Q. 'mode' を prerender にすると、もっと速くなりますか
→ 表示はさらに速くなりますが、移動しなかったページの画像やスクリプトまで読み込むので、通信量が大きく増えます。広告やアクセス解析のスクリプトによっては、読者が開いていないページで動いてしまうこともあるため、この記事では prefetch にしています。
おわりに(まとめ)
SWELLのPrefetchはオフにして、WordPress本体の先読みを moderate にすれば十分です。
- ✅ WordPress 6.8から、本体が先読み(Speculation Rules)を出力している。SWELLのPrefetchと二重になっていないか、ソースで確かめる
- ✅ SWELLのPrefetchは、PCではマウスが通り過ぎただけ、スマホではスクロールしただけで先読みする
- ✅ WordPressのHTMLにはキャッシュの指定がないため、SWELLの先読みはChromeで移動時に使われない
- ✅ 本体の先読みは先読み専用の場所から使われる。moderate にすると、移動先のTTFBが約190ms→約6msになった
- ✅ 一本化は、SWELLの設定を「使用しない」にして、functions.phpで eagerness を moderate にするだけ
この記事が、少しでも誰かのお役に立てれば幸いです。
関連記事
- 【WordPress高速化】X・Instagramの遅延読み込み:Intersection Observerで、XとInstagramの埋め込みを投稿に近づくまで読み込まない方法(シリーズ第8回)
- 【WordPress高速化】HCBを必要な記事だけで読み込む:Highlighting Code BlockのCSSとJSを、コードブロックがある記事だけで読み込む方法(シリーズ第7回)
- 【WordPress高速化】h3まで入れた目次の高さを自動設定:h2とh3を分けて数え、目次の高さを記事ごとに自動で確保する方法(シリーズ第6回)
- 【WordPress高速化】目次の高さを見出しの数で自動設定:PHPで見出しを数えてCSS変数に渡し、目次の高さを記事ごとに自動で確保する方法(シリーズ第5回)
- 【WordPress高速化】AdSenseを枠ごとに遅延読み込み:Intersection Observerで、画面に近づいた広告枠だけを読み込む方法(シリーズ第4回)
- 【WordPress高速化】YouTube埋め込みを遅延読み込み:Intersection Observerの基本と、画面外の動画の読み込みを0KBにした方法(シリーズ第3回)
- 【WordPress高速化】SWELLのCLSをCSSで改善:広告枠などに高さを確保して、CLSを0.14から0.0008に下げた実例(シリーズ第2回)
- 【WordPress高速化】CLSの原因を検証ツールで探す方法:検証ツールで、ずれた場所を見つけて高さを測る方法(シリーズ第1回)
※1回買えば複数サイトで使い回しOK
当サイトの記事で使用したVBAなどのサンプルをDLできます
この記事のサンプルはありません!
ダウンロードページへは下のカードをクリックすればジャンプできます。
よろしければご利用ください!


