Как избежать дублирования запроса при использовании wp_nav_menu?

Вопрос или проблема

Моя тема должна отображать 2 меню на главной странице. На остальных страницах нужно только одно. В результате только на главной странице появляется предупреждение о дублировании запроса. После исследования я выяснил, что это вызвано wp_nav_menu. Как избежать этой проблемы?

Вот скриншот моего предупреждения о дублировании:
Дублированный запрос

SELECT t.*, tt.*
FROM wp_terms AS t
INNER JOIN wp_term_taxonomy AS tt
ON t.term_id = tt.term_id
WHERE t.term_id = 163

И его вызывающий элемент:

  1. Lucidy\header()
    wp-content/themes/lucidy/engines/linker.php:86
  2. Lucidy\render()
    wp-content/themes/lucidy/engines/linker.php:79
  3. Lucidy\load()
    wp-content/themes/lucidy/engines/linker.php:48
  4. wp_nav_menu()
    wp-includes/nav-menu-template.php:120
  5. wp_get_nav_menu_object()
    wp-includes/nav-menu.php:26
  6. get_term()
    wp-includes/taxonomy.php:834
  7. WP_Term::get_instance()
    wp-includes/class-wp-term.php:131

Согласно отладчику, потенциальными источниками проблемы являются get_term_link и get_term_field. Однако я уверен, что не использую их напрямую. Они должны вызываться из wp_nav_menu. wp_nav_menu — главный подозреваемый, потому что на других страницах, таких как архив или одноэлементная страница, я не нахожу предупреждений о дублировании.

Это ошибка ядра? В любом случае, как мне ее избежать? В последнее время моя тема стала медленной (до 0,30–0,60 секунд времени рендеринга для главной страницы), и я хотел бы ее оптимизировать.

[Обновление 5 октября]
Извините, я забыл поделиться информацией о моем меню. У меня на самом деле есть 3 местоположения меню, и 2 из них размещены на главной странице. На главной странице я использую wp_nav_menu 2 раза.

Я регистрирую их в functions.php:

register_nav_menus([
    'menu_col' => __('Menu Column', 'lucidy'),
    'menu_list' => __('Menu List', 'lucidy'),
    'menu_bar' => __('Menu Bar', 'lucidy')
]);

Вы можете избежать этого, создав другое меню и местоположение для меню. Вы можете сделать это с помощью виджетной области или как угодно. Затем вызывайте меню только в том случае, если страница является главной страницей, с помощью is_home() или is_front_page(), если это страница.

Вот пример из twenty seventeen.

register_nav_menus(
    array(
        'top'    => __( 'Top Menu', 'twentyseventeen' ),
        'social' => __( 'Social Links Menu', 'twentyseventeen' ),
    )
);

и затем это вызывается так:

<?php if ( has_nav_menu( 'top' ) ) : ?>
    <div class="navigation-top">
        <div class="wrap">
            <?php get_template_part( 'template-parts/navigation/navigation', 'top' ); ?>
        </div>

Вы можете поместить в виджетные области практически все, что захотите. Я использую их на случай, если захочу вставить туда что-то еще.

В вашей ситуации меню — это “правильный” способ сделать это.

Ответ или решение

Для оптимизации работы вашей темы WordPress и предотвращения проблемы дублирования запросов при использовании функции wp_nav_menu, необходимо внести изменения в текущую реализацию отображения меню. Имейте в виду, что дублированные SQL-запросы могут замедлять работу сайта, особенно на главной странице, где у вас используется сразу два меню. Разберем теоретическую часть, подкрепим ее примерами и перейдем к практике.

Теория

На уровне ядра WordPress, функция wp_nav_menu используется для отображения навигационного меню. Она обращается к базе данных, чтобы получить информацию о терминах и таксономиях, связанных с элементами меню. Когда вы вызываете wp_nav_menu несколько раз на одной странице, это приводит к множественным запросам аналогичных данных, что и вызывает дублирование.

Ваша проблема может быть связана с тем, что на главной странице используется два меню, что увеличивает количество запрашиваемых данных и приводит к дублированию запросов. Это может быть не столько ошибка в ядре WordPress, сколько необходимость в оптимизации вызовов функции на уровне темы.

Пример

Рассмотрим пример, как можно организовать навигацию, чтобы избежать дублирования.

  1. Создание уникальных зон меню:

    Зарегистрируйте различные зоны меню в файле functions.php:

    register_nav_menus([
        'menu_col' => __('Menu Column', 'lucidy'),
        'menu_list' => __('Menu List', 'lucidy'),
        'menu_bar' => __('Menu Bar', 'lucidy')
    ]);

    Это определяет уникальные места для каждого меню.

  2. Условный вызов wp_nav_menu:

    Внутри вашего шаблона реализуйте проверку, используется ли wp_nav_menu только для домашней страницы:

    if (is_front_page()) {
        wp_nav_menu(['theme_location' => 'menu_col']);
        wp_nav_menu(['theme_location' => 'menu_list']);
    } else {
        wp_nav_menu(['theme_location' => 'menu_bar']);
    }

Применение

Теперь, когда мы понимаем, что основная проблема — это многочисленные вызовы wp_nav_menu, давайте рассмотрим, как мы можем решить эти проблемы на практике:

  1. Оптимизация вызовов wp_nav_menu:

    Убедитесь, что вы вызываете функцию только тогда, когда это необходимо, для предотвращения избыточных операций.

  2. Индексация и кэширование:

    Если ваш сайт динамичен и часто обновляется, рассмотрите возможность использования стороннего плагина кэширования, чтобы снизить нагрузку на базу данных, сохраняя HTML-страницы.

  3. Отладка и мониторинг:

    Используйте инструменты профилирования, например, Query Monitor для WordPress, чтобы идентифицировать и отслеживать дублирующие SQL-запросы. Это позволит более точно диагностировать проблему.

  4. Обновление темы и плагинов:

    Убедитесь, что все ваши темы и плагины обновлены до актуальных версий, так как устаревшее ПО может содержать неэффективный код.

Посредством этих шагов можно значительно улучшить производительность вашей темы и предотвратить возникновение дублированных запросов. Анализ времени работы и уменьшение количества обращений к базе данных обеспечат более быструю загрузку страниц вашего сайта, что положительно скажется на пользовательском опыте. Использование данных техник позволит добиться оптимального использования доступных ресурсов и улучшить общее качество работы сайта.

Оцените материал
Добавить комментарий

Капча загружается...