Оптимизация производительности сайта на WordPress часто требует внедрения кеширования. Большинство разработчиков прибегают к готовым плагинам, таким как WP Super Cache или W3 Total Cache, но иногда нужно создать кастомное решение, чтобы полностью контролировать поведение кеша и избежать конфликтов. В этой статье разберём, как сделать простой и эффективный кеш страниц и объектов без плагинов, используя возможности PHP и WordPress.
Почему стоит создавать собственный кеш в WordPress
Готовые плагины кеширования, хоть и удобны, могут быть избыточны для небольших проектов или специфичных условий. Кастомный кеш позволяет:
- Контролировать формат и логику хранения кеша.
- Минимизировать нагрузку на сервер за счёт оптимизированного кода.
- Избежать конфликтов с другими плагинами и темами.
- Настроить сроки жизни кеша под конкретные запросы.
Создание собственного кеша — отличный способ глубже понять работу WordPress и PHP, а также повысить скорость загрузки страниц.
Кеширование страниц с помощью файлов
Принцип работы
Идея в том, чтобы при первом запросе к странице сгенерировать HTML, сохранить его в файл и при последующих запросах отдавать содержимое файла, минуя генерацию страницы заново.
Реализация кеша страниц
Для начала создадим функцию wpacademy_cache_page(), которую подключим в functions.php темы или в отдельном файле, подключаемом через require_once.
function wpacademy_cache_page() {
if (is_user_logged_in()) {
// Не кешируем страницы для авторизованных пользователей
return;
}
$cache_dir = WP_CONTENT_DIR . '/cache/wpacademy-pages/';
if (!file_exists($cache_dir)) {
wp_mkdir_p($cache_dir);
}
$cache_file = $cache_dir . md5($_SERVER['REQUEST_URI']) . '.html';
// Время жизни кеша в секундах (например, 10 минут)
$cache_time = 600;
if (file_exists($cache_file) && (time() - filemtime($cache_file)) < $cache_time) {
// Отдаем кешированную страницу и останавливаем дальнейшую обработку
echo file_get_contents($cache_file);
exit;
} else {
// Запускаем буферизацию вывода
ob_start();
// Регистрируем функцию, которая сохранит кеш после генерации страницы
register_shutdown_function(function() use ($cache_file) {
$html = ob_get_contents();
if ($html) {
file_put_contents($cache_file, $html);
}
ob_end_flush();
});
}
}
add_action('template_redirect', 'wpacademy_cache_page');
Пояснения к коду
- Кеш не создаётся для авторизованных пользователей, чтобы не кэшировать персональный контент.
- Кеш хранится в директории
wp-content/cache/wpacademy-pages, которая создаётся при необходимости. - Имя файла кеша формируется как MD5 от URI запроса — это гарантирует уникальность для каждой страницы.
- Кеш обновляется каждые 10 минут, это значение можно настроить.
- Вывод страницы буферизуется, чтобы сохранить весь HTML в файл перед отправкой клиенту.
Кеширование объектов с помощью Transients API
Зачем кешировать объекты?
Многие операции в WordPress, например, запросы к базе данных, вызывают нагрузку. Transients API позволяет кешировать данные с определённым временем жизни, что ускоряет повторный доступ.
Пример кеширования результата запроса WP_Query
Допустим, нужно часто получать последние 5 публикаций из категории «Новости». Чтобы не выполнять запрос каждый раз, кешируем результат:
function wpacademy_get_latest_news() {
$transient_key = 'wpacademy_latest_news';
$cached = get_transient($transient_key);
if ($cached !== false) {
return $cached; // Возвращаем кешированные данные
}
$query = new WP_Query([
'posts_per_page' => 5,
'category_name' => 'news',
'post_status' => 'publish',
]);
$posts = [];
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
$posts[] = [
'title' => get_the_title(),
'permalink' => get_permalink(),
'date' => get_the_date(),
];
}
wp_reset_postdata();
}
// Сохраняем данные в кеш на 15 минут
set_transient($transient_key, $posts, 15 * MINUTE_IN_SECONDS);
return $posts;
}
Использование кешированных данных в шаблоне
В шаблоне можно вывести кешированные новости так:
$news = wpacademy_get_latest_news();
if (!empty($news)) {
echo '<ul>';
foreach ($news as $item) {
echo '<li><a href="' . esc_url($item['permalink']) . '">' . esc_html($item['title']) . '</a> (' . esc_html($item['date']) . ')</li>';
}
echo '</ul>';
} else {
echo '<p>Новости не найдены.</p>';
}
Дополнительные советы по кешированию в WordPress
Управление кешем при обновлениях контента
Кеш страниц и объектов должен инвалидироваться при изменении контента. Для кеша страниц можно добавить сброс кеша при сохранении записи:
function wpacademy_clear_page_cache_on_save($post_id) {
if (wp_is_post_revision($post_id)) return;
$cache_dir = WP_CONTENT_DIR . '/cache/wpacademy-pages/';
if (!file_exists($cache_dir)) return;
// Очистим весь кеш страниц (можно оптимизировать под конкретные URL)
$files = glob($cache_dir . '*.html');
if ($files) {
foreach ($files as $file) {
@unlink($file);
}
}
}
add_action('save_post', 'wpacademy_clear_page_cache_on_save');
Для Transients API достаточно сбросить кеш при обновлении нужных данных с помощью delete_transient('wpacademy_latest_news').
Использование кеша с учетом кеширования на уровне сервера
Если на сервере используется кеширование (например, Varnish, NGINX FastCGI Cache), то кастомное кеширование в WordPress можно совмещать с ним, отключая кеш для администраторов и авторизованных пользователей, как показано в примере выше.
Полезные плагины для расширения возможностей кеширования
Если в какой-то момент кастомный кеш покажется сложным или не покрывающим все требования, можно обратить внимание на плагины из WPSHOP.ru:
- Clearfy Pro — оптимизация и очистка WordPress, в том числе кеша и базы данных.
- ABC Pagination — улучшенная пагинация, которая может снизить нагрузку на сервер.
- WPRemark — расширенные комментарии с кешированием и оптимизацией.
Эти решения можно использовать в связке с кастомным кешем для лучшей производительности.