概要説明
WordPress で CSS や jQuery の読み込みをヘッダーからフッターに移す functions.php のコード。WordPress 6.9 以降はフッターの CSS がヘッダーに戻される仕組みと止め方、jQuery がヘッダーに戻ってしまうときの原因の調べ方を事例つきで。
~ 目次 ~
CSS をフッターに移す(WordPress 6.9 以降は注意)
表示を速くするために、すぐに使わない CSS や JavaScript をページの最後(フッター)で読み込む方法です。WordPress では、読み込みの予定を一度外して(dequeue)、フッターで入れ直します。
/*----------------------------------------------------
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 で確かめました)。どうしてもフッターに出したいときは、この仕組みを止めます。
// WordPress 6.9 以降:フッターに出した CSS をヘッダーに戻す仕組みを止める add_filter( 'wp_should_output_buffer_template_for_enhancement', '__return_false', 100 );
この仕組みを止めると、ブロックの CSS を必要な分だけ読み込む機能(クラシックテーマ向け)も働かなくなります。表示の速さは、止める前と後で PageSpeed Insights などで比べてから決めてください。
jQuery などのスクリプトをフッターに移す
スクリプトは、WordPress がスクリプトを登録する時点(wp_default_scripts)で「フッターに出す」の印を付けるのが確実です。
/*----------------------------------------------------
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 がヘッダーに残りました。どの処理がヘッダーで出しているかを、次のコードで調べました。
// 調べるときだけ使う:スクリプトを出した処理を 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 だけで済みます。こちらのほうが表示は速くなります。
/*----------------------------------------------------
使っていない 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 などで直接出している可能性があります。


