【WordPress】テーマに条件付きでCSSやJSを読み込む方法

WordPress

サイトの読み込み速度や管理のしやすさを高めるには、必要なページだけにCSSやJSを読み込むのが効果的です。WordPressではwp_enqueue_scriptsやadmin_enqueue_scriptsのフックと条件分岐タグを組み合わせることで、テーマに条件付きでアセットを読み込む実装が簡潔に行えます。ここではフロント用・管理画面用・ログイン画面用の基本から、依存関係やバージョニング、async/defer付与、不要アセットの抑制まで実運用で役立つパターンをまとめます。

基本:wp_enqueue_scriptsで条件分岐して読み込む

テーマのfunctions.phpに記述し、is_front_pageやis_page、is_singularなどの条件分岐タグで範囲を絞ります。ファイルの更新時刻をバージョンに使うとキャッシュ更新が自動化でき、依存配列で読み込み順も安全に制御できます。

<?php
add_action('wp_enqueue_scripts', function () {
  // 共通CSS(全ページ)
  $common_css = get_template_directory() . '/assets/css/common.css';
  wp_enqueue_style(
    'theme-common',
    get_template_directory_uri() . '/assets/css/common.css',
    [],
    filemtime($common_css),
    'all'
  );

  // トップページ限定のヒーロー用CSS
  if (is_front_page()) {
    $hero_css = get_template_directory() . '/assets/css/hero.css';
    wp_enqueue_style(
      'theme-hero',
      get_template_directory_uri() . '/assets/css/hero.css',
      ['theme-common'],
      filemtime($hero_css),
      'all'
    );
  }

  // 記事詳細のみJSを読み込む(jQueryに依存)
  if (is_singular('post')) {
    $article_js = get_template_directory() . '/assets/js/article.js';
    wp_enqueue_script(
      'theme-article',
      get_template_directory_uri() . '/assets/js/article.js',
      ['jquery'],
      filemtime($article_js),
      true
    );
  }

  // 固定ページ「/contact/」だけフォーム用JS
  if (is_page('contact')) {
    $form_js = get_template_directory() . '/assets/js/form.js';
    wp_enqueue_script(
      'theme-form',
      get_template_directory_uri() . '/assets/js/form.js',
      [],
      filemtime($form_js),
      true
    );
  }
});

投稿タイプやタクソノミーで条件分岐する

カスタム投稿タイプやアーカイブ画面など、URL設計に依存せず機能で出し分けると保守が楽になります。

<?php
add_action('wp_enqueue_scripts', function () {
  // カスタム投稿タイプ product の詳細ページ専用
  if (is_singular('product')) {
    $pjs = get_template_directory() . '/assets/js/product-single.js';
    wp_enqueue_script(
      'product-single',
      get_template_directory_uri() . '/assets/js/product-single.js',
      [],
      filemtime($pjs),
      true
    );
  }

  // product のアーカイブ・タクソノミー一覧
  if (is_post_type_archive('product') || is_tax('brand')) {
    $plist = get_template_directory() . '/assets/css/product-list.css';
    wp_enqueue_style(
      'product-list',
      get_template_directory_uri() . '/assets/css/product-list.css',
      ['theme-common'],
      filemtime($plist)
    );
  }
});

ブロック・ショートコードの存在に応じて読み込む

同じテンプレートでも、コンテンツ内の特定ブロックがあるときだけ資産を読み込むと無駄が減ります。ブロックエディタ編集画面ではhas_blockが使えないため、フロント向けの判定に限定します。

<?php
add_action('wp_enqueue_scripts', function () {
  if (is_singular() && has_block('core/gallery', get_the_ID())) {
    $gcss = get_template_directory() . '/assets/css/gallery.css';
    $gjs  = get_template_directory() . '/assets/js/gallery.js';
    wp_enqueue_style('theme-gallery', get_template_directory_uri().'/assets/css/gallery.css', [], filemtime($gcss));
    wp_enqueue_script('theme-gallery', get_template_directory_uri().'/assets/js/gallery.js', [], filemtime($gjs), true);
  }
});

スクリプトにasync/deferを付与する

読み込みブロッキングを避けたい場合はscript_loader_tagフィルターで対象ハンドルにだけ属性を付与します。依存関係があるものには付与しないなどのルール化が重要です。

<?php
add_filter('script_loader_tag', function ($tag, $handle) {
  $defer_targets = ['theme-article', 'theme-form', 'product-single'];
  if (in_array($handle, $defer_targets, true)) {
    // 末尾の ></script> を保ったまま defer を付ける
    $tag = str_replace('<script ', '<script defer ', $tag);
  }
  return $tag;
}, 10, 2);

不要なプラグインのCSS/JSを特定ページで解除する

プラグインが全ページでアセットを出す場合、対象外ページでだけデキューして軽量化できます。ハンドル名はソースを確認して合わせます。

<?php
add_action('wp_print_styles', function () {
  if (!is_page('contact')) {
    wp_dequeue_style('contact-form-7');
    wp_deregister_style('contact-form-7');
  }
}, 100);

add_action('wp_print_scripts', function () {
  if (!is_page('contact')) {
    wp_dequeue_script('contact-form-7');
    wp_deregister_script('contact-form-7');
  }
}, 100);

管理画面とログイン画面での条件付き読み込み

投稿・固定ページの編集画面だけ、あるいは特定の設定ページだけに管理用アセットを読み込むと、管理画面の体感速度が上がります。ログイン画面は専用フックを使います。

<?php
// 管理画面
add_action('admin_enqueue_scripts', function ($hook) {
  // 投稿作成・編集画面だけ
  if (in_array($hook, ['post.php', 'post-new.php'], true)) {
    $admin_css = get_template_directory() . '/assets/admin/editor-help.css';
    wp_enqueue_style(
      'editor-help',
      get_template_directory_uri() . '/assets/admin/editor-help.css',
      [],
      filemtime($admin_css)
    );
  }
  // 固有の設定ページだけ(例:toplevel_page_theme-settings)
  if ($hook === 'toplevel_page_theme-settings') {
    $admin_js = get_template_directory() . '/assets/admin/settings.js';
    wp_enqueue_script(
      'theme-settings',
      get_template_directory_uri() . '/assets/admin/settings.js',
      ['jquery'],
      filemtime($admin_js),
      true
    );
  }
});

// ログイン画面
add_action('login_enqueue_scripts', function () {
  $login_css = get_template_directory() . '/assets/css/login.css';
  wp_enqueue_style(
    'login-style',
    get_template_directory_uri() . '/assets/css/login.css',
    [],
    filemtime($login_css)
  );
});

wp_register_*で登録してから必要時だけenqueueする

大きなライブラリは常時読み込まず、登録だけ行い、条件を満たしたときにenqueueすると管理しやすくなります。

<?php
add_action('wp_enqueue_scripts', function () {
  wp_register_script(
    'swiper',
    'https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.js',
    [],
    '10.0.0',
    true
  );
  wp_register_style(
    'swiper',
    'https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.css',
    [],
    '10.0.0'
  );

  if (is_page_template('templates/page-slider.php')) {
    wp_enqueue_style('swiper');
    wp_enqueue_script('swiper');
    $slider_js = get_template_directory() . '/assets/js/slider-init.js';
    wp_enqueue_script('slider-init', get_template_directory_uri() . '/assets/js/slider-init.js', ['swiper'], filemtime($slider_js), true);
  }
});

実運用のチェックポイントとトラブル回避

条件分岐はis_*タグの評価タイミングに注意し、wp_enqueue_scriptsの中で使うようにします。依存関係の崩れはハンドル名の誤りで起きやすいため、親のハンドルを依存配列に正しく指定します。キャッシュが更新されない場合はfilemtimeでのバージョニングを導入し、CDN利用時はクエリ文字列の扱いポリシーに合わせてファイル名ハッシュ方式も検討します。プラグイン資産のデキューは高い優先度でフックするか、出力順を確認してから実施すると安定します。

まとめ

WordPressの条件分岐タグとenqueue周りのフックを組み合わせれば、テーマに必要十分なCSS・JSだけを読み込む設計が実現できます。ページ種別や投稿タイプ、ブロック存在、管理画面の画面種別などの条件で出し分け、バージョニングやdefer付与、不要アセットの抑制までを一連のルールとして整備すると、表示速度と保守性の両方を高水準で保てます。“`