Tips

WordPressでclean_urlフィルターでのdefer、asyncの付与はNG

記事内に商品プロモーションを含む場合があります

WordPressでテーマやプラグインで使われるJavaScriptを遅延や非同期読み込みするために、clean_urlを使ってdeferやasyncの属性を付与していたのですが、WordPress6.4以降は問題が発生します。原因と対処策についてお伝えします。

ある日PageSpeed Insightsで問題に気づく

ある日、PageSpeed Insightsでサイト速度の計測してみました。

そこで問題が起きていることに気がつきました。

「レンダリングをブロックしているリクエスト」の項目に、以前は表示されていなかったスクリプトまで表示されていることに気がつきました。

しかも、 js/jquery/jquery.min.js?ver=3.7.1' defer charset='UTF-8 のように文字化けしているかのようなURLが表示されていました。

WordPress6.4でURLがエスケープされる仕様変更

いろいろ調べて原因がわかりました。以下にあるように、WordPress 6.4から、scriptタグのURLがエスケープされる仕様になったためです。

Script loading changes in WordPress 6.4

これまで、scriptタグにdefer属性を不要する場合、以下のように、clean_urlフィルターを利用していました。

これを、子テーマのfunction.phpやオリジナルのプラグインのplugin.phpに記載します。

この手法は、本来のclean_urlの使い方ではなく、トリッキーな使い方ですが、以下など多くのサイトでこの方法が紹介されていて、私も使っていました。

async属性でレンダリングをブロックするJavaScriptにfunction.phpに記述で対処

WordPress6.4から、scriptタグのURLがエスケープされるようになったため、シングルクオテーションが、 &#039 に変換されてしまい、上述したURLになったということでしょう。

読み込まれなくなってしまえば、すぐに気がつけたのでしょうが、 ? 以降の全ての文字列がバージョン番号かのように機能したため、読み込みは同期で行われていて、しばらく気がつけませんでした。この間、多くの読者さんに、表示が遅いなぁと思わせてしまった可能性があります。

clean_urlを使う方法はもうダメ

あまり大幅な変更をしたくなかっため、clean_urlフィルターを使う方法でdeferやasyncを付与できないか検討しました。シングルクオテーションではなくダブルクオテーションはどうか、バックスラッシュでエスケープするのはどうか、など試しましたが、全部ダメでした。

正攻法は当該ファイルをenqueueし直す

WordPress6.3でdeferやasyncはJavaScriptを登録する wp_register_script() や wp_enqueue_script() で指定できるようになりました。

なので、テーマやプラグインでしっかりdeferやasyncを指定していない場合は、子テーマやオリジナルのプラグインで、 wp_enqueue_script() で指定し直すことで付与できます。

ちなみに、以下で説明したように、 wp_enqueue_script() の引数の中には、一度、 wp_deregister_script() してからでないと反映されないものもあります。

しかし、私が検証した結果、ここで変更したいstrategyという部分は、 wp_deregister_script() しなくても反映されます。

WordPressのenqueue、register、dequeue、deregisterのポイントWordPressでscriptタグを操作するために、wp_enqueue_script() 、wp_register_script()...

script_loader_tagフィルターを使う

ただ、上述したenqueueし直すという正攻法は、一個ずつ対応する必要があります。

例えば、新しいプラグインを導入したとして、そこで使われるJavaScriptにdeferやasync が付与されていない場合、その度に子テーマやオリジナルのプラグインを修正して対応する必要があります。

流石にそれは面倒臭いので、clean_urlのようにフィルターで全体に対応できたら楽です。以下の記事でscript_loader_tagでできることがわかりました。

[WordPress] script要素にdefer/asyncを付与する方法

こちらはclean_urlと違って、URLだけでなくタグ全体を編集できるので、URLのエスケープの影響を受けずにdeferやasyncを付与できます。

私の場合、ちょっと置換の方法を変えて以下のようにdeferを付与しています。

WordPressのアプデで悪い影響を受けないために

そもそも、WordPressのアップデートで、このような大きな変更がある場合、通知する仕組みがあれば良いのにと思いました。例えば、clean_urlフィルターを子テーマやプラグインで使っていれば、検知してアラートを出すなどはできるのではないでしょうか。

こちらで対応できることとしては、WordPressのアップデート時はPageSpeed Insightsで確認する習慣をつければ、このようなことを防げる可能性が高いので今後はしていきます。

さいごに

clean_urlフィルターを使ってasyncやdeferを付与していると起きる問題についてご説明しました。

上記の対処策で対応できますので、参考にしてみてください。

そして、一つお願いしたいことがあります。

もしこの記事がお役に立てたのなら、下のボタンからSNSでシェアするか、あなたのブログでご紹介頂けないでしょうか?検索エンジンの仕組みで、同じ問題で今困っている方の目に届きやすくなります。もちろん、私としても記事を書くモチベーションになります。

記事への要望やダメ出しを書いて頂いても嬉しいです。定期的にエゴサーチしており、今後の記事で活かさせて頂きます。よろしくお願いいたします!