Help us understand the problem. What is going on with this article?

【爆速】WordPressで始めるpjax入門

More than 3 years have passed since last update.

AWS+KUSANAGIでWordPressサイトを運用しており、その時点でかなり速かったのですが、さらに高速化するべくpjax(barba.js)を導入しました。
導入後、ページ遷移体感速度が5000兆倍になったので導入方法をシェアします。

barba.jsとは

pjax(非同期画面遷移)を使いやすくしたjsライブラリ。
これを使うとページ遷移時にコンテンツ部分のみを読み込むことができ、
まるでネイティブアプリを使っているようなページ遷移を体験できます。
また、animation、prefetch、cache等に対応しています。

デモサイト

barba.jsを導入しているサイトのご紹介。
Grid Demo(公式)
Next/Prev Demo(公式)
Circles Demo(公式)
Accueil | Effektiv, cabinet de recrutement(非公式)
Famiglia Cecchi | Official site(非公式)

導入手順

1. 必要なファイルの準備

必要なファイルは2つ。
barba.js本体とカスタム用のjsファイル。
今回本体はCDNで読み込みますので、まずはカスタム用のjsファイルを作成して、
WordPressで使用しているテーマディレクトリにブチ込んでください。

今回はbarba-custom.jsという名前で作成します。
アップロード先の例:wp-content/themes/yourtheme/js/barba-custom.js

2. jsファイルの読み込み

barba.js本体と先ほど作成したjsを読み込みます。
functions.phpに下記コードをコピペしてください。
※wp_enqueue_script()の第5引数をtrueにすると</body>タグの直前で読み込まれ、
falseにすると<head>タグ内で読み込みます。

function my_enqueue_scripts() {
   // barba.js本体の読み込み
   wp_enqueue_script(
      'barba',
      '//cdnjs.cloudflare.com/ajax/libs/barba.js/1.0.0/barba.min.js',
      array(),
      '1.0.0',
      true
   );
   // barbar-custom.jsの読み込み
   wp_enqueue_script(
      'barba-custom',
      get_template_directory_uri() . '/js/barba-custom.js',
      array(),
      false,
      true
   );
}
add_action( 'wp_enqueue_scripts', 'my_enqueue_scripts' );

※jQueryが読み込まれていない場合はjQueryも読み込んでください。

3. テーマファイルのHTML書き換え

書き換え対象ファイル例:
・home.php
・index.php
・single.php
・archive.php
・category.php
・tag.php
・page.php
・search.php

上記ファイルの非同期で読み込みたい部分(コンテンツ部分)を下記のタグで囲みます。
ヘッダー、サイドバー、フッターは基本的に固定になると思いますので、
それ以外の部分を下記タグで囲うを良いでしょう。

.php
<div id="barba-wrapper">
  <div class="barba-container">
    <!-- 動的コンテンツ -->
  </div>
</div>

home.phpの書き換え例

home.php
<?php get_header(); ?>

<div id="content" class="clearfix">
  <div id="contentInner">
    <div id="barba-wrapper"> <!-- ←追加した -->
      <div class="barba-container"> <!-- ←追加した -->
        <div class="main">
          <article>
            <div class="sidebar">
              <?php get_template_part('list'); ?>
              <?php get_template_part('pagenavi'); ?>
            </div>
          </article>
        </div>
      </div> <!-- ←追加した -->
    </div> <!-- ←追加した -->
  </div>
  <?php get_sidebar(); ?>
</div>

<?php get_footer(); ?>

書き換え対象ファイルは、ご自身でお使いのテーマやpjaxさせたいページに合わせて適宜変更してください。
※pjaxさせたくないリンクには.no-barbaを付けると無効化されます。

4. barba-custom.jsの編集

最後にbarba-custom.jsに下記コードをコピペしてbarba.jsを有効化しましょう。
ご自身の環境に合わせて適宜変更してください。
cacheはデフォルトで有効になっています。

barba-custom.js
// 現在と同じページのリンクをクリックした場合、リロードをしない設定(オプション)
// リロードしたい場合は削除してOKです。
var links = document.querySelectorAll('a[href]');
var cbk = function(e) {
 if(e.currentTarget.href === window.location.href) {
   e.preventDefault();
   e.stopPropagation();
 }
};
for(var i = 0; i < links.length; i++) {
  links[i].addEventListener('click', cbk);
}

/* 
* 遷移時に変更したい処理
* デフォルトではhead内のmetaタグは変わりません。(titleタグは変わります)
* また、barba-container内のjsは実行されないので個別に変更・実行したい処理をココに書きます。
*/
Barba.Dispatcher.on('newPageReady', function(currentStatus, oldStatus, barbaContainer, newPageRawHTML) {

   if ( Barba.HistoryManager.history.length === 1 ) {  // ファーストビュー
      return; // この時に更新は必要ありません
   }

   // jquery-pjaxから借りた
   var $newPageHead = $( '<head />' ).html(
      $.parseHTML(
         newPageRawHTML.match( /<head[^>]*>([\s\S.]*)<\/head>/i )[ 0 ],
         document,
         true
      )
   );
   // 変更したいタグ(ご自身の環境に合わせて適宜変更してください)
   var headTags = [
      "link[rel='canonical']",
      "link[rel='shortlink']",
      "link[rel='alternate']",
      "meta[name='description']",
      "meta[property^='og']",
      "meta[name^='twitter']",
      "meta[name='robots']"
   ].join( ',' );
   $('head').find(headTags).remove(); // タグを削除する
   $newPageHead.find(headTags).appendTo('head'); // タグを追加する

   // Analyticsにヒットを送信(Google Analyticsを導入している場合)
   if (typeof ga === 'function') {
      ga('send', 'pageview', location.pathname);
   }

   // 外部ファイルを任意の場所に追加して実行する(オプション)
   // 外部ファイルにdocument.write()が書かれていると、それは無視されますので正常に表示されません。
   var script = document.createElement('script');
   script.src = 'http://example.com/hoge.js';
   document.body.appendChild(script);

   // インラインに書いたjsを実行する(オプション)
   var temp = document.createElement('div');
   temp.innerHTML = newPageRawHTML;
   var hoge = temp.querySelector('.hoge script');
   if(hoge != null){
      eval(hoge.innerHTML);
   }

}); // End Dispatcher

// アニメーションの設定(フェードアウト→フェードイン)(オプション)
// 必要ない場合は削除してOKです。
var fadeTransition = Barba.BaseTransition.extend({
   start: function() {
      //startはトランジションが起動した直後の一番最初に呼び出される。

      //promise.allを使うと、配列で渡された処理が全て終わった後に.thenを実行。
      //この場合は.newContainerLOadingと.fadeOutが終わってから.thenが実行される。
      Promise
         .all([this.newContainerLoading, this.fadeOut()])
         .then(this.fadeIn.bind(this));
   }, // End start function

   fadeOut: function() {
      //古いページコンテンツに対して行う処理。
      //ここでは、animateを使って、fadeoutさせている。
      return $(this.oldContainer).animate({ opacity: 0 },{duration:'fast'}).promise();
   },

   fadeIn: function() {
      // topに移動(地味に重要)
      document.body.scrollTop = 0;

      //startに記述したallによって、fadeOutが終わったらこのfadeIn関数が呼び出されている。

      var _this = this;
      //ここでのnewContainerは、ajaxで読み込まれてきた新しい方の.barba-containerにあたる。
      var $el = $(this.newContainer);

      //opacity:0;になっていた古いbarba-containerをdisplay:none;に。
      //こちらおそらくfadeIn発動時古いbarba-containerの初期設定として。
      $(this.oldContainer).hide();
      //こちらも新しいbarba-containerの初期設定。
      //visiblityがあるのは、デフォルトではこれがhiddenになってるっぽいから。
      $el.css({
         visibility : 'visible',
         opacity : 0
      });

      $el.animate({opacity: 1}, 200, function() {
         //.done()をつけることで古いbarba-containerのDOMは削除され、transitionが終了する。
         _this.done();
      });
   }
}); // End BaseTransition

// returnに作ったトランジションを設定
Barba.Pjax.getTransition = function() {
   return fadeTransition;
};

// barba実行
$().ready(function(){
   Barba.Pjax.start();
   Barba.Prefetch.init(); // prefetchを有効化
});

参考記事・サイト

Barba.js
Barba.jsを使って、metaタグを動的に更新する方法
シームレスなページ遷移を!PJAXの実装に便利な軽量プラグイン Barba.js の使い方 | あらかぜ手帖
Scripts within container are not evaluated · Issue #32 · luruke/barba.js · GitHub
Google Analytics Issue · Issue #88 · luruke/barba.js · GitHub
Page reloaded · Issue #34 · luruke/barba.js · GitHub

Simmon
とにかく速いWordPressテーマ「Godios.」の作者。 公式サイト→https://godios.simmon.design/ ブログ→https://blog.simmon.design/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away