トイレのうず

WordPressのEmbedのheadに不要なJavaScriptやCSSが出力されるのを修正する

当記事はアフィリエイト広告を掲載しています。

WordPress 標準で使えるブログカードの機能 (Embed) ですが、なんだか表示が遅く使い物にならないな、と思っていました。 Firefox の Firebug のネットワークにて読みこまれているファイルを調べてみると、原因は Embed の <head> に不要な JavaScript や CSS が読み込まれていることでした。それらの読み込みが完了するまでレンダリングされないので、表示が遅くなっていました。なので出力されないように手を加えました。

読み込んでいたファイルは jQuery と emoji のライブラリ のほか、 Photo Express for Google という Google Photos の写真を表示させるプラグインや WP SyntaxHighlighter というコードを見やすくするプラグインの JavaScript や CSS が読み込まれていました。 Embed 内では写真もコードも表示させることもないから、これらの JavaScript は必要ありません。

Embed 内の emoji のライブラリ削除

WordPress の Embed は使っている人が少ないからか、 Embed 内の emoji ライブラリ 「 wp-emoji-release.min.js 」を非表示にするアクションフックがわからなかったのですが、アクションフックの規則性から embed_head でいけるのではないかと思って試してみたらビンゴでした。(下記コードの 3 行目。)下記はその他のページでも絵文字を停止するフック一式です。

function disable_emojis() {
	remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
	remove_action( 'embed_head', 'print_emoji_detection_script' );
	remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
	remove_action( 'wp_print_styles', 'print_emoji_styles' );
	remove_action( 'admin_print_styles', 'print_emoji_styles' );   
	remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
	remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );     
	remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
	add_filter( 'tiny_mce_plugins', 'disable_emojis_tinymce' );
	add_filter( 'emoji_svg_url', '__return_false' );
}
add_action( 'init', 'disable_emojis' );

jQuery の読み込みのアクションフックを変更

jQuery が Embed にも出力されるのは以前 jQuery の読み込みを WordPress ではなく Google に変更するのに使ったアクションフックが適切でなかったためでした。

変更前:

function load_cdn() {
    if ( !is_admin() ) {
        wp_deregister_script('jquery');
        wp_enqueue_script('jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js', array(), '1.11.0');
    }
}
add_action('init', 'load_cdn');

このコードの問題点は 2 つあり、まずはアクションフックに init を使っているところと、 wp_enqueue_script() で登録しているところです。

init は WordPress の読み込み終了後ヘッダーが送信される前のタイミングに実行されるので、管理画面や Embed を表示するときにも動いてしまうのです。なのでこれを wp_enqueue_scripts に変更します。変更前のコードでは if 文で管理画面は除外してありますが、 wp_enqueue_scripts は Web サイト側のみに効くフックなので、 if 文は必要なくなります。

また wp_enqueue_script() は enqueue に登録して出力しているので、 jQuery を使用しないページの <head> にも出力されてしまいます。なので登録のみを行う wp_register_script() に変更しました。これにより依存するスクリプトを指定したときのみ読み込むようになります。(依存関係は wp_enqueue_script() や wp_register_script() での第 3 引数の配列で設定します。)

以上を踏まえて以下のように変更しました。

変更後:

function load_cdn() {
    wp_deregister_script('jquery');
    wp_register_script('jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js', array(), '1.12.4', true );
}
add_action('wp_enqueue_scripts', 'load_cdn');

最後の引数に true がついているのは、レンダリングのブロックさせないために必要なければフッター(</body> 直前)で jQuery を読みこませるためです。依存するコードとして登録されている場合に jQuery が読み込まれますが、そのコードが <head> で読み込まれるときは jQuery も <head> で読み込まれます。

Embed 内の Photo Express for Google の CSS 削除

Embed 内の Photo Express for Google の CSS を削除するために、enqueue に登録されている CSS を登録から外す関数の wp_deregister_style() を使って、wp_enqueue_scripts でフックしてみたのですが、削除されず困りました。

Photo Express for Google のコードを見てみると、コードを登録するためのフックに init を使っているのです。init は先程も述べましたように WordPress の読み込み終了後ヘッダーが送信される前のタイミングに実行されます。つまり wp_enqueue_scripts よりあとに実行されるので、init を使って登録したものは wp_enqueue_scripts では削除されないわけです。

init のフックで登録から除外すればいいのですが、CSS を登録するタイミングは wp_enqueue_scripts が推奨されているので、Photo Express for Google のプラグインを書き換えました。(Photo Express for Google が更新されたら変更箇所は元に戻ってしまうけれど、もう 2 年更新されておらず作者が更新するつもりがなさそうなので問題ないでしょう。)

Photo Express for Google プラグイン内の photo-express.php の 190 行目の initwp_enqueue_scripts に書き換えます。続いて登録されている JavaScript の部分についても 3 か所書き換えました。(196、202、213行目。)

変更前:

add_action( 'init', array( &$this->display, 'peg_add_display_css' ) );

変更後:

add_action( 'wp_enqueue_scripts', array( &$this->display, 'peg_add_display_css' ) );

wp_enqueue_scripts に JavaScript や CSS を登録しても Embed には出力されないので、対策はこれで終わりです。

Embed 内の WP SyntaxHighlighter の JavaScript と CSS を削除

WP SyntaxHighlighter は 5 年も更新されていないので、違うプラグインに変更しようかと思ったのですが、あまりよいものがなかったので、こちらも対応しました。

wp-syntaxhighlighter.php にてスクリプトが登録されているアクションフックが、wp_footer だったので、wp_enqueue_scripts に変更しました。

928 行目と 933 行目あたりの 2 か所です。

変更前:

add_action('wp_footer', 'wp_sh_check_valid_tag');

変更後:

add_action('wp_enqueue_scripts', 'wp_sh_check_valid_tag');

wp_sh_load_scripts_on_footer() 関数内で直接 <script> タグを直接書き出していたため、wp_deregister_script() で削除できないので、wp_enqueue_script を使ったコードに書き換えました。変更が多岐に渡っているので詳細は書きません。違うプラグインに変更するのが一番早い解決方法だと思います。

スタイルシートは wp_print_styles で登録されていたのでそのままでも、wp_enqueue_scripts のアクションフックで登録抹消することができるのですが、ついでなので変更しました。(wp_print_styleswp_enqueue_scripts より前に実行されるので削除できるようです。)

853 行目です。

変更前:

add_action('wp_print_styles', 'wp_sh_load_style');

変更後:

add_action('wp_enqueue_scripts', 'wp_sh_load_style');

以下は syntaxhighlighter を使わない時に CSS から取り除くためのコードです。function.php に書くことで対応しました。これはだいぶ前に施策したものです。

function my_deregister_script() {
	$post_id = get_the_ID();
	if(!get_post_meta($post_id, 'wp_syntaxhighlighter', true)){
		wp_deregister_style('core3.0');
		wp_deregister_style('core-Default3.0');
		wp_deregister_style('theme-Default3.0');
	}
}
add_action('wp_enqueue_scripts', 'my_deregister_script');

get_post_meta() で取得しているのは投稿時にカスタムフィールドに WP SyntaxHighlighter を使っている場合は true と入力しており、これによって表示するコードがない場合はヘッダーに CSS を読み込まないようにしています。

これまでにプラグインで使われてきた JavaScript/CSS を登録するアクションフック

使用しているいくつかのプラグインにて wp_enqueue_scripts のアクションフックで、 enqueue に登録されている JavaScript や CSS を削除や再登録してみようと思ったところ、削除されないものがありました。原因は Photo Express for Google などのように wp_enqueue_scripts のアクションフックで JavaScript や CSS を登録していない古いプラグインです。 wp_enqueue_scripts は WordPress 2.8.0 にて導入されたようで、古いソースを引き継いでいるプラグインはほかのアクションフックを使っているものもあるようです。 wp_enqueue_scripts で上手く削除できない場合は JavaScript や CSS が登録されたときのフックが何か確認してみるとよいでしょう。

以下プラグインで JavaScript や CSS を登録するために使われていたアクションフックです。

  • wp_enqueue_scripts (推奨)
  • wp_print_styles (非推奨)
  • wp_print_scripts (非推奨)
  • init ( wp_enqueue_scripts で削除できない)
  • wp_head ( wp_enqueue_scripts で削除できない)
  • wp_footer ( wp_enqueue_scripts で削除できない)

Javascript や CSS を enqueue に登録するとき WordPress 3.3 より wp_print_styles と wp_print_scripts ではなく wp_enqueue_scripts を使うことを推奨されています。

また外部読み込みの JavaScript に付随するコードは WordPress 4.5 から wp_add_inline_script() という関数で追加できるようになったようです。これ以前は付随するコードでも wp_head や wp_footer で挿入していたようです。同じく CSS の場合は、 wp_add_inline_style() という関数が使えます。こちらは WordPress 3.3 から使用できるようです。

関連記事

WordPress で「スクロールせずに見えるコンテンツのレンダリングをブロックしている JavaScript/CSS を排除する」に対応する
WordPress
thumbnail above the fold(ファーストビュー、スクロールせずに見える領域)
WordPress のブログカードが表示されないのは Permalink Redirect のせいなので動くように改造した
WordPress
thumbnail Permalink Redirectを無効にするとWordPress標準のブログカードが表示される
外部サイトの画像を WordPress のサイトアイコンに設定する
WordPress
thumbnail ブログカードのサイトアイコンがWordPressのデフォルト
暇つぶしに WordPress の本を読む
WordPress
thumbnail ぼやき
レスポンシブ対応画像の遅延読み込み時に再レンダリングされるのを防止する方法
WordPress
thumbnail 画像の高さが未指定だと画像遅延読み込みで再レンダリングされる
WordPress にソーシャルボタンを Fontello の Web フォントを使って設置する方法
WordPress
thumbnail Fontello