2026年6月20日

2026年6月20日

WordPressのサイドバーを最適化する方法・ページ別表示制御とパフォーマンス改善

はじめに

「トップページだけサイドバーを非表示にしたい」「サイドバーの読み込みが遅い」——WordPressのサイドバーはページ種別に応じた表示制御とキャッシュ最適化で大きく改善できます。

症状・原因

サイドバーが全ページで同じウィジェットを表示すると、ランディングページや全幅レイアウトページに不要なコンテンツが表示されます。また、各ウィジェットが毎回DBクエリを実行すると、ページ全体のパフォーマンスが低下します。

解決手順

ステップ1:ページ種別でサイドバーを出し分ける

// テンプレートファイルでの条件分岐
function show_sidebar() {
    // サイドバーを非表示にするページ
    if ( is_front_page() ) return false;   // トップページ
    if ( is_page_template( 'full-width.php' ) ) return false; // 全幅テンプレート
    if ( is_404() ) return false;           // 404ページ
    if ( is_search() ) return false;        // 検索結果
    return true;
}

// sidebar.phpの呼び出し
if ( show_sidebar() ) {
    get_sidebar();
}
// カスタムウィジェットをページ種別で出し分ける
class Conditional_Sidebar_Widget extends WP_Widget {

    public function widget( $args, $instance ) {
        $show_on = $instance['show_on'] ?? 'all';

        // 表示条件をチェック
        $should_show = match ( $show_on ) {
            'singular' => is_singular(),
            'archive'  => is_archive(),
            'home'     => is_home(),
            default    => true,
        };

        if ( ! $should_show ) return;

        echo $args['before_widget'];
        // コンテンツ出力
        echo $args['after_widget'];
    }
}

ステップ2:ウィジェットキャッシュでパフォーマンスを向上する

// Transients APIでウィジェット出力をキャッシュ
class Cached_Recent_Posts_Widget extends WP_Widget {

    public function widget( $args, $instance ) {
        $cache_key = 'widget_recent_posts_' . $this->id;
        $cached    = get_transient( $cache_key );

        if ( $cached !== false ) {
            echo $cached;
            return;
        }

        ob_start();
        echo $args['before_widget'];

        $posts = get_posts( [ 'numberposts' => 5 ] );
        echo '<ul>';
        foreach ( $posts as $post ) {
            echo '<li><a href="' . get_permalink( $post ) . '">'
                . esc_html( get_the_title( $post ) ) . '</a></li>';
        }
        echo '</ul>';
        echo $args['after_widget'];

        $output = ob_get_clean();
        set_transient( $cache_key, $output, HOUR_IN_SECONDS );
        echo $output;
    }

    public function update( $new_instance, $old_instance ) {
        // ウィジェット更新時にキャッシュを削除
        delete_transient( 'widget_recent_posts_' . $this->id );
        return $new_instance;
    }
}

ステップ3:スティッキーサイドバーを実装する

// テーマのfunctions.phpでスクリプトを読み込み
add_action( 'wp_enqueue_scripts', function() {
    if ( is_singular() ) {
        wp_enqueue_script(
            'sticky-sidebar',
            get_stylesheet_directory_uri() . '/js/sticky-sidebar.js',
            [],
            '1.0',
            true
        );
    }
} );
// js/sticky-sidebar.js - シンプルなスティッキーサイドバー
document.addEventListener('DOMContentLoaded', function() {
    const sidebar  = document.querySelector('.sidebar');
    const content  = document.querySelector('.main-content');
    if (!sidebar || !content) return;

    const observer = new IntersectionObserver(
        ([entry]) => {
            sidebar.classList.toggle('is-sticky', !entry.isIntersecting);
        },
        { threshold: 0, rootMargin: '-80px 0px 0px 0px' }
    );
    observer.observe(document.querySelector('.site-header'));
});
/* CSS: スティッキーサイドバー */
.sidebar {
    position: sticky;
    top: 20px;
    max-height: calc(100vh - 40px);
    overflow-y: auto;
}

ステップ4:モバイルでサイドバーをアコーディオン表示する

// モバイルでサイドバーをアコーディオン化
document.addEventListener('DOMContentLoaded', function() {
    if (window.innerWidth > 768) return;

    const widgetTitles = document.querySelectorAll('.widget-title');
    widgetTitles.forEach(function(title) {
        const content = title.nextElementSibling;
        if (!content) return;

        content.style.display = 'none';
        title.style.cursor    = 'pointer';
        title.setAttribute('aria-expanded', 'false');

        title.addEventListener('click', function() {
            const isOpen = content.style.display !== 'none';
            content.style.display = isOpen ? 'none' : 'block';
            title.setAttribute('aria-expanded', String(!isOpen));
        });
    });
});

ステップ5:サイドバーのHTMLキャッシュを出力する

// サイドバー全体をObject Cacheでキャッシュ
function get_cached_sidebar( $sidebar_id ) {
    $cache_key = 'sidebar_' . $sidebar_id . '_' . get_locale();
    $cached    = wp_cache_get( $cache_key, 'sidebars' );

    if ( $cached ) {
        echo $cached;
        return;
    }

    ob_start();
    dynamic_sidebar( $sidebar_id );
    $output = ob_get_clean();

    wp_cache_set( $cache_key, $output, 'sidebars', 3600 );
    echo $output;
}

// 投稿更新時にサイドバーキャッシュを削除
add_action( 'save_post', function() {
    wp_cache_delete( 'sidebar_main-sidebar_' . get_locale(), 'sidebars' );
} );

注意事項

  • サイドバーをキャッシュする場合、ログイン状態・ユーザー権限・言語別にキャッシュキーを分けないと、管理者限定コンテンツが非ログインユーザーに表示される危険があります。
  • position: stickyはIE11以降とモバイルブラウザで概ね対応していますが、親要素にoverflow: hiddenが設定されていると機能しません。
  • サイドバーのHTMLキャッシュはウィジェット更新・投稿公開時に適切にクリアする必要があります。キャッシュが残ると古いコンテンツが表示され続けます。

まとめ

サイドバー最適化は「ページ別表示制御→ウィジェットキャッシュ→スティッキー実装→モバイルアコーディオン→全体キャッシュ」の組み合わせで実現できます。特にウィジェットのキャッシュはサイト全体のパフォーマンスに直結します。関連記事:WordPressでウィジェットをカスタマイズする方法WordPressの表示速度を改善する方法

お気軽にご相談ください

お見積りへ お問い合わせへ