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がfalseに設定されています。
no_found_rowsがfalseだと何が起こるかというと全ての記事数を取得します。
これはページネーションを行う際に使用するもので、ページネーションを使わない場面(関連記事など)では無駄な処理が増えるのでtrueに設定しています。

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

Lazy Load

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

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

pjaxの導入

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

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

その他の高速化

正直、テーマだけではdev.to速度を出すことは厳しいと思います。
公式サイトではサーバー側での対策も行いましたのでざっと書いておきます。

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

※CDNは使っていません。

PageSpeed Insights

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

PC
speed-insights-pc.png

アナリティクス・アドセンスが入ってるのでこんなもんですかね。