WordPressのページキャッシュのせいでis_mobile()を使った分岐が死んでいた

WordPressのページキャッシュのせいでis_mobile()を使った分岐が死んでいた
みるみ

自分で

  • is_mobile()
  • wp_is_mobile()

などを使ってWordPressをカスタマイズしている人はちょっと注意した方がいいかもしれません。ページキャッシュによって、意図したデバイスでの分岐が得られなくなっている可能性がかなりあるからです。

この発見に至る経緯、原因と対策についてまとめます。

あるとき些細な異常を見つけた

スマホでなんとなくこのブログをチェックしていたとき、オリジナルで作った専用メニューがちゃんと動作しないことがあるのを発見。

my-original-phone-menu-button-customize

これ。

JSはちゃんと読み込まれている、PCのデベロッパーツールだとちゃんと動く、たまに動くことがある、、、などでもう「???」です。

しかもページネーションも意図した表示になっていないことにも気付きました。

my-original-pagination-customize

これ。

PCとスマホで表示を変えているんですが、自分でfunctions.phpに書いて作ったものなので「アルゴリズム間違ってたのかな?」とか思って直す→その場で確認するとOK!→翌日確認するとまたダメ→規則性不明→「???」という感じ。

そこで気付く。

どちらの実装にもis_mobile()関数を使ってデバイスの分岐を行っているという共通点がありました。

さらに。

以前、サーバー引っ越しをしたときに高速化やキャッシュ系機能のまとめを行ったのですが、このときに「ページキャッシュ用のプラグイン」も導入していました。

ゆえに立てた仮説は

is_mobile()によってPC(スマホ)で表示されたHTMLがそのままキャッシュされ、PHPの分岐を通る前にそのHTMLが出力されてしまっている

となりました。

実際のところ、is_mobile()を削除しなくても手動でキャッシュを削除した直後は意図した表示になっていました。これが決め手で原因を確信。

なにが起きている?

なにが起こっているのか整理します。

まず分かっているのは以下。

  1. is_mobile()の分岐内にいても、JavaScriptは読み込まれる
  2. どのページでどうキャッシュが使われるかは不規則(に見える)
  3. スマホ側でPC用の表示になってしまうことはあるが、PCでスマホ用の表示になったことは一度も確認できていない

上2つはどうでもいいんだけど、3つめはポイントです。

これは「スマホ表示時はキャッシュしないから」みたいな設定が生きているせいかと睨んだんですが、ページキャッシュプラグインである「WP Fastest Cache」の設定を見た感じどうやらビンゴ。

wp-fastest-cache-settingpng

上から6個目。そもそも無料版ではここはONにできない。

っていうかそもそもスマホのときはキャッシュで表示されてなかったんかい!

まあ結果的に解決したので気にしない気にしない…。

対策は?

対策は大きく2通りに分かれます。

  1. ページキャッシュをやめる
  2. is_mobile()をやめる

当然です。

しかし高速化の費用対効果からページキャッシュは外せない。となるとis_mobile()を使うのを全面的にやめるしかないです。

幸い前述した2つの異常はCSSで簡単に対応可能だったのであっさり削除できました。PC時に不要なJSが1つ多くなるけど、誤差だよ誤差。

AdSenseだけ困った

唯一困ったのがGoogle AdSense。

レポートのためを思って同じ場所でもPC用とスマホ用で広告ユニットを分けていました。

my-adsense-unit-list

今は整理中なので命名規則がめちゃくちゃです。

単純にそれぞれに適したユニットに出し分けたいとも思っていた。

しかし最近のAdSenseチームの取り組みを見ると「できる限りサイト運営者が選べる広告の種類数は減らし、Googleが極力レスポンシブで勝手に出稿する」みたいな印象を受けます。

というわけで、「いい機会だし」と思ってAdSenseはPCもスマホも1つにまとめました。久しぶりに新しい広告を作ったけど、ほぼレスポンシブの設定しかなくて設定項目もめちゃ少ない。

new-create-new-adsense-unit

2019年はAdSenseのアップデートが盛んでしたね。

公式ヘルプを見てもなるべくレスポンシブから固定設定に変えないことが推奨されているし、これで良さそう。

from-official-help-forum

あと注意点として、AdSenseにdisplay:none;などのCSSをあてるのはポリシー違反になるので気をつけてください。

from-official-help-forum-2

レスポンシブ対応で表示を変えるときは決まった対応が必要です。参考→AdSenseヘルプフォーラム

おわりに

「ただのif文を使った分岐なのに、それだけでページキャッシュを使うと破綻するなんて、そんなことあり得る?」と激しく思ったんですが、そもそも表示するたびに表示が変わるような分岐ってis_mobile()以外にはないという事実に改めて気付き、驚きました。

テーマファイルでも死ぬほど使われているif文ですが、それらは毎回分岐結果が変わるものではありません。

  • 設定の値を取得する
  • 現在のページの種別を取得する

などなど、だいたいはこんなところ。定期的なキャッシュ更新が行われていれば全く問題がないんですよね。

大きく設定を変えたら反映を見るために自分でキャッシュ削除はするし、WP Fastest Cacheでも記事更新や投稿のたびにキャッシュは自動削除されるようになっています。

昔「レスポンシブデザインをis_mobile()で」という間違いだらけの作業を反省したこともあったのに、またこいつに困らされるとは…。

今後この関数を使うことはないなという気がしています。

使っている方はぜひご注意を!

おまけ

気付いた方がいるかどうか分かりませんが、実はWP Fastest Cacheの設定で「モバイルのときはキャッシュで表示しない」という設定があったので、そこにチェックを入れればたぶん解決していた…。笑

wp-fastest-cache-settingpng

上から5個目。隣なのになぜ気付かなかった…。

しかしまあ、こういうのは根本的に解決したほうが将来的にも良いはずなので、今回は良かったはずです。うん、そう思おう()

みるみ
みるみ

ブロガー、ソフトウェアエンジニア。

文章を書くのが好きです。サイトは全部自分でつくっています。

この記事へのコメント
コメントはまだひとつもありません :)

新しいコメントを書く

  • 必須項目はコメント本文のみですが、お名前はぜひご記入いただけると嬉しいです。
    ※メールアドレスを書いた場合も公開されることはないのでご安心ください。
  • 特定のコメントに返信したい場合は各コメントにある「返信する」ボタンからどうぞ。
  • コメントはこちらで承認の作業を行うまでは表示されません。ご了承ください。
    ※ここ数年スパムが激化しており、誤って削除されてしまうケースが増えてきました。スパムボックスも毎日自分の目で確認するようにはしているのですが、どうしても限界があります。確実に僕に連絡を取りたい方は メールTwitter からお願いします。