swup + WordPressで従来のテーマをサクッとPjax化してみた
今回は、従来の形式で作成した WordPress テーマを、お手軽に Pjax 化してみたので、ポイントと導入手順を簡潔にまとめます。

Pjax化のメリット
Pjax(Partial Ajax)とは、ページ全体をリロードせず、一部だけを非同期通信で差し替える実装です。カッコいいサイトでよく見かける挙動ですね。
今回使用した swup は、Pjax 機能を軽量かつシンプルに導入できる JavaScript ライブラリです。
ページ遷移時のチラつきが減る
ブラウザのフルリロードが発生しないため、ページ遷移時に画面が一瞬消えるようなチラつきがなくなります。
体感速度が向上する
実際の読み込み速度以上に、「サクサク動いている」という体感をユーザーに与えやすくなります。
パフォーマンスの改善の可能性
構成や設計によって効果には差がありますが、ページ全体の再読み込みや DOM の再構築が減ることで、メモリ使用量の削減や PageSpeed Insights のスコア向上など、パフォーマンス指標の改善につながるケースもあります。
導入方法
バンドラーへの追加と初期化
npm から swup をインストールします。
npm install swupswup をインポートして、インスタンスを作成します。
import Swup from "swup";
const swup = new Swup();対象のDOMにIDを追加
非同期で読み込ませるコンテンツに id=”swup” を追加します。
<main>を対象にする場合、WordPress テーマでは以下のような形になります。
header.php
...
<main id="swup">footer.php
</main>
...実はもう、これだけで Pjax 化できました。簡単すぎて感動。
パーマリンク設定やページネーションなど、WordPress の基本的な仕組みも、概ね問題なく動作します。
遷移時のトランジションをつける
このままだと表示がパッと切り替わるだけなので、遷移時にフェードアウト・フェードインのアニメーションを追加しましょう。
main にクラスを追加します。
<main id="swup" class="transition-fade">swup が に付与するクラスを利用して、CSS トランジションも設定します。
/* ページ遷移開始時 */
html.is-changing .transition-fade {
transition: opacity 0.25s;
opacity: 1;
}
/* ページ切り替え中 */
html.is-animating .transition-fade {
opacity: 0;
}これで、
フェードアウト → コンテンツ差し替え → フェードイン
という自然な遷移になります。
Pjaxの注意点と対策
<main id=”swup”> 内のコンテンツや <title> はページ遷移によって書き換わりますが、それ以外の要素はそのまま残ります。
そのため、公式プラグインや swup の Hooks を使って対策をします。
head内の要素
WordPress の SEO プラグインなどが出力する meta / ogp / schema などの動的な書き換えは、Head Plugin の導入で解決します。
npm install @swup/head-pluginimport SwupHeadPlugin from "@swup/head-plugin";
const swup = new Swup({
plugins: [new SwupHeadPlugin()],
});Google Analytics へのイベント送信
Pjax のページ遷移では、GoogleAnalyticsのページビューイベントが計測されないため、 GTM Plugin の導入で解決します。
npm install @swup/gtm-pluginimport SwupGtmPlugin from "@swup/gtm-plugin";
const swup = new Swup({
plugins: [new SwupGtmPlugin()],
});JavaScriptの再読み込みや発火
Pjax では、ページ遷移後に DOMContentLoaded が再発火しません。
そのため、遷移後に必要な初期化処理を自分で呼び直す必要があります。
たとえば HOME 固有の初期化設定をする場合は
// 初期化フラグ
let homeInited = false;
// 初期化
function homeInit() {
if (homeInited) return; // 初期化済みなら何もしない
homeInited = true;
// home専用の初期化処理
...
}
// 破棄
function homeDestroy() {
// home以外では不要になる、イベントリスナーやタイマーの解除など
...
// 再訪問時に初期化できるようフラグを戻す
homeInited = false;
}
// home判定(ページ固有の要素で識別など)
function isHome() {
return !!document.querySelector("#home-contents");
}
// 初回ロード時
if (isHome()) {
homeInit();
}
// コンテンツを置き換えた後
swup.hooks.on("page:view", () => {
if (isHome()) {
homeInit();
}
});
// 別のコンテンツに置き換える前
swup.hooks.on("content:replace", () => {
if(homeInited) {
homeDestroy();
}
});というような感じです。
利用している WordPress プラグインによっては、同様に初期化や発火の処理を加える必要があります。
特に Pjax の場合の注意点として、イベントリスナーやタイマーなどの登録が蓄積しやすく、メモリリークや挙動不良の原因になるため、不要になった処理は適切なタイミングで破棄することが重要です。
また、ページ単位で JS や CSS を分割している場合は、ページ遷移後にそれらが読み込まれないため、ファイルを1本化して管理する設計に寄せる必要があります。
PjaxはSEOに弱いのか?
SPA や Pjax は SEO に不向きというイメージを持たれがちですが、WordPress + swup の構成では、各ページは通常通り存在するという状態を保てます。JavaScript 無効時でも閲覧可能です。
そのため、一般的な WordPress サイトであれば、検索エンジンにクロールされる情報自体は従来と変わらないので、SEOに弱くなることは無いと言えます。
パフォーマンス指標の改善によっては、検索エンジンからの評価が上がることも期待できると思います。
まとめ
JavaScript を多用し、ページごとに複雑な初期化や状態管理が必要なサイトでは、Pjax 導入による 設計・保守コストの方が高くなる ため、今回のような「後付け」での Pjax 化はあまりオススメできません。
一方で、構成がシンプルな WordPress サイトであれば、比較的低コストで Pjax 化が可能で、UX やパフォーマンス指標の向上が見込めるケースも多そうです。
そんなときの選択肢として、swup はかなり使いやすいライブラリだと感じました。
今回使用した swup のほかにも、同じような Pjax ライブラリとして、barba.js や htmx なども良さそうなので、これらもおいおい試してみたいなと思います。