PHP
CSS
JavaScript
WordPress
高速化

dev.toに匹敵する速度を出せるWordPressテーマを開発した話

本日、無料WordPressテーマ Godios. をリリースしました。

demo.gif

公式サイトを見ていただけるとわかると思うのですがページが一瞬で遷移しています。
どうでしょう、dev.toと同じくらい速いんじゃないでしょうか。

この記事ではテーマを高速化するにあたって用いたテクニックを書いていきたいと思います。

圧縮

テーマに含まれている画像・CSS・JSファイルの圧縮。
画像はOptimizillaTinyPNG、CSSはCSS Minifier、JSはJSCompressを使用しました。

CSS・JSファイルの遅延読み込み

レンダリングをブロックするファイルが大量にあると表示が遅くなりますので、JSファイルはdeferまたはasync属性を付与し、CSSファイルはインライン、またはJSで非同期に読み込んでいます。

無駄なSQLクエリを減らす

データベースへのアクセスが多いと負荷が掛かる上、速度的にも影響が出るため不必要なクエリを省きました。
具体的には、get_theme_mod()でテンプレートごとに設定値を一回一回取得するのではなく、functions.phpでget_option()を使い、一度に全ての設定値を取得しグローバル変数に格納。テンプレートではグローバル変数から設定値を使うようにしています。

WP_Queryのno_found_rowsをtrueに設定

記事を取得する時に使うWP_Queryですが、パラメータにno_found_rowsを設定しないとデフォルトでno_found_rowsがfalseとして実行されます。
no_found_rowsがfalseだと何が起こるかというと全ての記事数を取得します。
これはページネーションを行う際に使用するもので、ページネーションを使わない場面(関連記事など)では無駄な処理が増えるのでno_found_rowsをtrueに設定しています。

記事数がほとんどない状況ではそんなに影響はないと思いますが、1000、1万と増えてきた場合に影響が出てきます。
ましてやテンプレート毎にfalseで実行された場合、悲惨なことになります。(いつでもどこでもno_found_rowsを設定していないテーマを良く見かけます。)

Lazy Load

読み込み速度向上のため、Lazy Load(画像・iframeの遅延読み込み)を導入しました。
Lazy Load有効時、不可視範囲のimgタグにダミー用の極めて小さいインライン画像を読込み、可視範囲に入った際に本来の画像を読み込むようにしています。

ライブラリはlazysizesを使いました。
当初、Layzr.jsを使っていたのですが、後述するpjaxとの相性が良くなかったためlazysizesに変更。

pjaxの導入

高速化に関して、これが一番効果がありました。
pjax有効時、ヘッダー・フッター・サイドバーはファーストビューでのみ読込み、2回目からはコンテンツ部分のみを読み込むようにしています。
ライブラリはBarba.jsを使用。
プリフェチをデフォルトで有効化しています。

jQueryではなく素のJavaScriptで(※追記 2018/4/26)

当初pjaxの遷移処理をjQueryを使って行っていましたが、機能追加に伴い動作がモッサリしてきたので8・9割方素のJavaScriptで書き換えました。
計測してみるとjQueryは素のJavaScriptに比べて数倍から数十倍遅かったので、こういった速度を追い求めるものには向いていないですね。便利ですが。

以上がテーマ側で行った施策になります。

その他の高速化

正直、テーマだけではdev.to速度を出すことは厳しいと思います。
公式サイトではサーバー側での対策も行いましたのでざっと書いておきます。(逆にGodios.を使ってサーバー側での対策をしっかり行えばこれくらいの速度は誰でも出せるということです。)

サーバー:KUSANAGI for AWS
インスタンスタイプ:t2.small
・PHP 7.2
・SSL対応
・HTTP/2対応
・bcache、fcacheの有効化
・ブラウザキャッシュの有効化
・gzip圧縮転送有効化

※CDNは使っていません。

PageSpeed Insights

最後にトップページのPageSpeed Insightsの点数を載せておきます。
スマホ
speed-insights-sp.png

PC
speed-insights-pc.png

アナリティクス・アドセンスが入ってるのでその分がマイナスになっています。