WordPress で CSS・JavaScript をヘッダーからフッターに移す(6.9 以降の注意と、jQuery が戻るときの調べ方)

広告WordPress・PHP を学べる本

Amazonのアソシエイトとして、WordPress functions.phpは適格販売により収入を得ています。

概要説明

WordPress で CSS や jQuery の読み込みをヘッダーからフッターに移す functions.php のコード。WordPress 6.9 以降はフッターの CSS がヘッダーに戻される仕組みと止め方、jQuery がヘッダーに戻ってしまうときの原因の調べ方を事例つきで。

表示を速くするために、すぐに使わない CSS や JavaScript をページの最後(フッター)で読み込む方法です。WordPress では、読み込みの予定を一度外して(dequeue)、フッターで入れ直します。

functions.php
/*----------------------------------------------------
 CSS をヘッダーからフッターに移す
----------------------------------------------------*/
if ( ! function_exists( 'fs_move_css_to_footer' ) ) {
    function fs_move_css_to_footer() {
        $handles = array( 'my-style' ); // フッターに移したい CSS のハンドル名
        foreach ( $handles as $handle ) {
            if ( wp_style_is( $handle, 'enqueued' ) ) {
                wp_dequeue_style( $handle ); // ヘッダーでは出さない
                add_action(
                    'wp_footer',
                    function () use ( $handle ) {
                        wp_enqueue_style( $handle ); // フッターで出す
                    },
                    5 // フッターの CSS が出る(優先度 20)より前に入れる
                );
            }
        }
    }
    add_action( 'wp_enqueue_scripts', 'fs_move_css_to_footer', 100 );
}

「my-style」は、移したい CSS のハンドル名(wp_enqueue_style の 1 つ目の値)に変えてください。ハンドル名は、ページのソースの <link> の id から「-css」を除いたものです。

WordPress 6.9 以降は、フッターの CSS がヘッダーに戻される

WordPress 6.9 から、クラシックテーマ(ブロックテーマでないテーマ)では、フッターで出した CSS を、WordPress がページを出し終えたあとに自動でヘッダーへ移すようになりました(wp_hoist_late_printed_styles)。CSS をあとから読むと、一瞬レイアウトが崩れて見えるのを防ぐためです。

そのため、上のコードだけでは、ページのソースを見ても CSS はヘッダーにあります(2026 年 10 月・WordPress 7.1 で確かめました)。どうしてもフッターに出したいときは、この仕組みを止めます。

functions.php
// WordPress 6.9 以降:フッターに出した CSS をヘッダーに戻す仕組みを止める
add_filter( 'wp_should_output_buffer_template_for_enhancement', '__return_false', 100 );

この仕組みを止めると、ブロックの CSS を必要な分だけ読み込む機能(クラシックテーマ向け)も働かなくなります。表示の速さは、止める前と後で PageSpeed Insights などで比べてから決めてください。

スクリプトは、WordPress がスクリプトを登録する時点(wp_default_scripts)で「フッターに出す」の印を付けるのが確実です。

functions.php
/*----------------------------------------------------
 jQuery をヘッダーからフッターに移す(管理画面は変えない)
----------------------------------------------------*/
if ( ! function_exists( 'fs_move_jquery_to_footer' ) ) {
    function fs_move_jquery_to_footer( $scripts ) {
        if ( is_admin() ) {
            return;
        }
        foreach ( array( 'jquery', 'jquery-core', 'jquery-migrate' ) as $handle ) {
            $scripts->add_data( $handle, 'group', 1 ); // 1 = フッターに出す
        }
    }
    // WordPress がスクリプトを登録するとき(ほかの処理より先)に印を付ける
    add_action( 'wp_default_scripts', 'fs_move_jquery_to_footer', 20 );
}
  • group を 1 にすると、WordPress はそのスクリプトをフッターで出します。
  • wp_enqueue_scripts で印を付けると、ほかの処理が先に読み込みの順番を計算していた場合に、間に合わないことがあります。そのため、登録の時点で付けます。
  • ヘッダーで jQuery を使うスクリプト(インラインの jQuery(…) など)があるときは、移すとエラーになります。移したあとは、ブラウザの開発ツールのコンソールに「jQuery is not defined」が出ていないか確かめてください。

前に載せていたコードの問題

以前は、ヘッダーで jquery-core の登録を消し(wp_deregister_script)、フッターで登録し直す(wp_register_script)コードを載せていました。この方法には、次の問題がありました。

  • 登録し直すだけでは読み込まれない(enqueue されない)ので、jQuery を頼りにするスクリプトがないページでは、jQuery が出ない。
  • ヘッダーで jQuery を使う処理(下の事例のプラグインなど)が、jQuery より先に動いてエラーになる。
  • 圧縮していない jquery.js を、版の番号なしで読み込む。

フッターに移らないときの調べ方(事例:プラグインが jQuery をヘッダーに戻していた)

上のコードを入れても、このサイトでは jQuery がヘッダーに残りました。どの処理がヘッダーで出しているかを、次のコードで調べました。

functions.php
// 調べるときだけ使う:スクリプトを出した処理を debug.log に書く(終わったら消す)
add_filter( 'print_scripts_array', function ( $todo ) {
    $trace = array();
    foreach ( array_slice( debug_backtrace(), 2, 8 ) as $f ) {
        $trace[] = ( isset( $f['file'] ) ? basename( $f['file'] ) : '' ) . ':' . ( isset( $f['function'] ) ? $f['function'] : '' );
    }
    error_log( 'print_scripts ' . implode( ',', $todo ) . ' <= ' . implode( ' / ', $trace ) );
    return $todo;
} );

debug.log(wp-config.php で WP_DEBUG_LOG を有効にしたときのログ)に、次のように出ました。

print_scripts jquery-core,jquery-migrate,jquery <= class-wp-scripts.php:apply_filters / class-wp-dependencies.php:all_deps / functions.wp-scripts.php:do_items / wp-most-popular.php:wp_print_scripts / class-wp-hook.php:javascript / ...

人気の記事を数えるプラグイン「WordPress Most Popular」が、ヘッダーの処理(wp_head)の中で wp_print_scripts( ‘jquery’ ) を呼んで、jQuery をその場で出していました。さらにその直後に、閲覧数を数える jQuery.post(…) をヘッダーに書き出しています。

  • このプラグインを使っている限り、jQuery はヘッダーで読み込む必要があります(フッターに移すと、閲覧数が数えられなくなります)。
  • このプラグインの処理を外したときは、上のコードで jQuery がフッターに移ることを確かめました。

同じように、プラグインやテーマが wp_print_scripts でスクリプトを直接出していると、フッターに移せません。移らないときは、まず上のコードで「どの処理が出しているか」を確かめるのが近道です。調べ終わったら、このコードは消してください。

使っていないものを読み込ませないだけなら

フッターに移すのではなく、使っていない CSS・JavaScript を読み込ませないだけなら、dequeue だけで済みます。こちらのほうが表示は速くなります。

functions.php
/*----------------------------------------------------
 使っていない CSS・JavaScript を読み込ませない
----------------------------------------------------*/
if ( ! function_exists( 'fs_remove_unused_assets' ) ) {
    function fs_remove_unused_assets() {
        wp_dequeue_style( 'wp-block-library' ); // ブロックエディタの CSS(ブロックを使っていない場合)
        wp_dequeue_script( 'comment-reply' );   // コメントの返信(コメントを使っていない場合)
    }
    add_action( 'wp_enqueue_scripts', 'fs_remove_unused_assets', 100 );
}

wp_dequeue と wp_deregister の違い

  • wp_dequeue_style / wp_dequeue_script:「このページで読み込む」という予定から外す。登録は残るので、あとから入れ直せる。フッターに移すときや、ページによって出し分けるときはこちら。
  • wp_deregister_style / wp_deregister_script:登録そのものを消す。それを頼りにしているほかの CSS・スクリプトも出なくなる。jquery-core など WordPress の基本の登録を消すと、思わぬところが動かなくなるので、使うときは注意が要る。

どちらでも消えないときは、テーマやプラグインが <link> や <script> を直接書いている(ハードコーディングしている)か、上の事例のように wp_print_scripts などで直接出している可能性があります。

参考

関連機能

  1. Chrome の「カバレッジ」で使われていない CSS・JavaScript を探す:WordPress のテーマを軽くする手順

  2. WordPress 特定のページでプラグインの有効・無効の制御ができるプラグイン Plugin Load Filter

  3. WordPress の自動更新を止める:更新のお知らせは消さずに、手で安全に更新する設定

サイドバー

よく使うカスタマイズ

最近の記事

Profile

PAGE TOP