Вопрос или проблема
Моя тема должна отображать 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
И его вызывающий элемент:
- Lucidy\header()
wp-content/themes/lucidy/engines/linker.php:86 - Lucidy\render()
wp-content/themes/lucidy/engines/linker.php:79 - Lucidy\load()
wp-content/themes/lucidy/engines/linker.php:48 - wp_nav_menu()
wp-includes/nav-menu-template.php:120 - wp_get_nav_menu_object()
wp-includes/nav-menu.php:26 - get_term()
wp-includes/taxonomy.php:834 - 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, сколько необходимость в оптимизации вызовов функции на уровне темы.
Пример
Рассмотрим пример, как можно организовать навигацию, чтобы избежать дублирования.
-
Создание уникальных зон меню:
Зарегистрируйте различные зоны меню в файле
functions.php
:register_nav_menus([ 'menu_col' => __('Menu Column', 'lucidy'), 'menu_list' => __('Menu List', 'lucidy'), 'menu_bar' => __('Menu Bar', 'lucidy') ]);
Это определяет уникальные места для каждого меню.
-
Условный вызов
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
, давайте рассмотрим, как мы можем решить эти проблемы на практике:
-
Оптимизация вызовов
wp_nav_menu
:Убедитесь, что вы вызываете функцию только тогда, когда это необходимо, для предотвращения избыточных операций.
-
Индексация и кэширование:
Если ваш сайт динамичен и часто обновляется, рассмотрите возможность использования стороннего плагина кэширования, чтобы снизить нагрузку на базу данных, сохраняя HTML-страницы.
-
Отладка и мониторинг:
Используйте инструменты профилирования, например, Query Monitor для WordPress, чтобы идентифицировать и отслеживать дублирующие SQL-запросы. Это позволит более точно диагностировать проблему.
-
Обновление темы и плагинов:
Убедитесь, что все ваши темы и плагины обновлены до актуальных версий, так как устаревшее ПО может содержать неэффективный код.
Посредством этих шагов можно значительно улучшить производительность вашей темы и предотвратить возникновение дублированных запросов. Анализ времени работы и уменьшение количества обращений к базе данных обеспечат более быструю загрузку страниц вашего сайта, что положительно скажется на пользовательском опыте. Использование данных техник позволит добиться оптимального использования доступных ресурсов и улучшить общее качество работы сайта.