Оптимизация WordPress при помощи кэширования меню
На сайтах с большим количеством пунктов в меню создаётся множество ненужных запросов в базу данных, которых можно избежать, если закэшировать всё меню в транзитный кэш.
Решения
Для кэширования меню меню существуют два популярных решения: плагин cache-nav-menus от самих Automattic и плагин Menu Cache от Inpsyde.
Рассмотрим более подробно каждый из них.
Описание
Этот плагин повышает производительность меню навигации в WordPress двумя способами.
Во-первых, он перехватывает все запросы на генерацию меню и включает внутренний механизм кэширования WP_Query
.
Во-вторых, он предоставляет новую функцию wpcom_vip_cached_nav_menu()
на замену стандартной wp_nav_menu()
, которая оборачивает основную функцию, эффективно кэшируя выходные данные, чтобы уменьшить количество запросов, выполняемых на сайте.
Использование
Для использования всей мощи данного решения устоновите плагин из архива и замените в шаблоне сайте все вызовы wp_nav_menu()
на wpcom_vip_cached_nav_menu()
.
Описание
Функция wp_nav_menu()
вызывает функцию _wp_menu_item_classes_by_context()
, которая снова и снова, в зависимости от контекста, вызывает функцию wp_get_object_terms()
, которая не кэшируется и так происходит несколько раз.
С большим количеством таксономий, терминов в пунктах меню пропорционально растет количество запросов к базе данных.
Этот плагин позволяет вам кэшировать меню (при условии, что они не имеют динамических компонентов) для повторного использования.
Установка
Данный плагин можно установить через Composer, главное, чтобы на сайте был РНР 5.4 и выше:
composer require inpsyde/menu-cache
Использование
После активации плагин автоматически начинает кэшировать все меню по умолчанию на пять минут.
Фильтры
Кэшируемые меню, а также срок действия могут быть настроены с помощью соответствующего фильтра.
Для изменения времени кэширования меню используйте фильтр \Inpsyde\MenuCache\MenuCache::FILTER_EXPIRATION
(задаётся в секундах):
add_filter(
\Inpsyde\MenuCache\MenuCache::FILTER_EXPIRATION,
function () {
return 600;
}
);
Для изменения названия ключа в базе данных используйте фильтр Inpsyde\MenuCache\MenuCache::FILTER_KEY
(можно отдельно для кажлого меню):
add_filter(
\Inpsyde\MenuCache\MenuCache::FILTER_KEY,
function ( $key, $args ) {
return "cached_menu_{$args->theme_location}";
},
10,
2
);
Фильтр Inpsyde\MenuCache\MenuCache::FILTER_KEY_ARGUMENT
позволяет настроить имя аргумента меню, которое используется для хранения ключа меню:
add_filter(
\Inpsyde\MenuCache\MenuCache::FILTER_KEY_ARGUMENT,
function () {
return '_menu_key';
}
);
Фильтр Inpsyde\MenuCache\MenuCache::FILTER_SHOULD_CACHE_MENU
позволяет настраивать кэширование для каждого меню:
add_filter(
\Inpsyde\MenuCache\MenuCache::FILTER_SHOULD_CACHE_MENU,
function ( $should_cache_menu, $args ) {
// Cache all menus for a bunch of dynamically created theme locations.
return 0 === strpos( $args->theme_location, 'some_prefix_here_' );
},
10,
2
);
Фильтр Inpsyde\MenuCache\MenuCache::FILTER_THEME_LOCATIONS
позволяет определять местоположения тем, к которым следует применить кэширование:
add_filter(
\Inpsyde\MenuCache\MenuCache::FILTER_THEME_LOCATIONS,
function () {
return 'primary';
}
);
Хорошо бы замеры эффективности в цифрах привести, насколько изменяется ответ сервера. Иначе, это может быть всего лишь нано-улучшения.
Был у меня сайт, где в многоуровневом меню было порядка 40+ категорий товаров, которые раз в сутки менялись по крону в зависимости от наличия в них товаров. При включении кэширования меню количество запросов в базу уменьшилось на 240 и скорость загрузки всей страницы на 1 секунду.
Если на сайте уже используется кеширующий плагин, нужно ли также заниматься и ставить плагины из статьи для кеша меню и виджетов?
Если у вас полностраничный кеш — смысла ставить отдельный плагин для кешировнаия меню нет, если только у вас не все пользователи авторизованные.