SDWSKi Cache. Плагин кеширования для WordPress
проекте
Плагин страничного кэша для WordPress с режимом интернет-магазина. SDWSKi Cache отдаёт готовые HTML-страницы ещё до загрузки WordPress, хранит их сразу в сжатом виде и аккуратно обходит кэш там, где страница зависит от конкретного посетителя: корзина, личный кабинет, комментарии, закрытые записи.
Этот проект — это GPL-плагин страничного кэша, написанная на стандартных правилах кеширования в системе WordPress: основа принципов кеширования сохранена, а ядро отдачи, режим WooCommerce, интерфейс и защита от конфликтов написаны полностью с нуля.
Задача
Стандартные кэш-плагины хорошо работают на блогах и плохо на магазинах. Типичные проблемы, которые я хотел закрыть:
- в кэш попадает страница с чужим счётчиком корзины;
- в карточке товара остаётся старый остаток;
- многоязычный сайт отдаёт посетителю страницу не на его языке;
- при сбое оптимизации (минификация, объединение файлов) пользователь видит пустой экран;
- в админке полно рекламы и ссылок на сторонний сайт.
Архитектура
Плагин состоит из трёх уровней, каждый из которых решает свою часть задачи.
1. Загрузчик (sdwski-cache.php). Решает только одно: можно ли запускать движок. Если на сайте уже активен оригинальный плагин или другая копия, загрузчик ничего не подключает, не регистрирует хуки и показывает уведомление с кнопкой «Отключить и запустить». Все классы, функции и константы движка имеют собственные префиксы, поэтому ошибки вида «Cannot redeclare» исключены, в каком бы порядке WordPress ни загрузил плагины.
2. Движок (sdwski-engine.php, inc/). Классический слой: генерация и очистка кэша, минификация и объединение CSS/JS, предзагрузка, правила исключений, CDN (в том числе Cloudflare), очистка Varnish, модуль безопасности, планировщик очистки, WP-CLI. Здесь же перехватывается вывод страницы через output buffer.
3. Turbo-слой (inc/turbo/). Мой основной вклад. Это drop-in advanced-cache.php, который WordPress подключает раньше темы и плагинов, и ядро turbo-core.php, которое управляет его настройками, статусом и очисткой.
Как работает отдача из drop-in
Порядок проверок в advanced-cache.php выстроен так, чтобы при любом сомнении отдать запрос WordPress:
- Обрабатываются только запросы
GET. - Запросы бота предзагрузки всегда уходят в WordPress, чтобы страница была создана или обновлена.
- Хост и схема (http/https) должны совпадать с адресом сайта, что покрывает варианты с
wwwи без него. - Если в cookie есть признаки вошедшего пользователя, комментатора, защищённой паролем записи или сессии магазина, посетитель получает живую страницу. Список можно расширить своими именами cookie.
- Только после этого ищется готовый файл в кэше.
Если файл найден, ответ собирается без запуска WordPress. В заголовках отдаются Vary: Accept-Encoding, ETag и X-ruzi-Turbo: HIT, который удобно проверять в браузере или через curl -I.
Предсжатые копии и условные запросы
Сжатие выполняется один раз при создании страницы, а не при каждом запросе. Рядом с index.html лежат index.html.gz и, если на сервере есть расширение brotli, index.html.br. Drop-in смотрит на заголовок Accept-Encoding и отдаёт подходящий вариант. На условный запрос с совпавшим ETag отвечает 304 без чтения файла.
При очистке кэша удаляются все варианты страницы: обычный, gzip и brotli, а также постраничная навигация и копии по языкам. Это защищает от «осиротевших» сжатых файлов, которые иначе пережили бы удалённую страницу.
Режим интернет-магазина (WooCommerce)
Самая объёмная часть работы. Правила дублируются на трёх уровнях: в .htaccess, в drop-in и в движке, поэтому защита не зависит от одного переключателя.
| Задача | Решение |
|---|---|
| Чужая корзина в кэше | Посетитель с товарами в корзине или сессией магазина всегда получает живую страницу, его запрос не создаёт общий кэш |
| Корзина, оформление, кабинет | Эти страницы не кэшируются вообще |
| Устаревший остаток и цена | Изменение товара, остатка, цены, статуса или заказа очищает кэш. Режим по умолчанию: весь кэш. Работают хуки woocommerce_update_product, woocommerce_order_status_changed и transition_post_status |
| Импорты в обход WooCommerce | Максимальный возраст кэша, по умолчанию 3 часа |
| Счётчик корзины в шапке | В кэше всегда ноль, реальное число подставляется небольшим скриптом по заданному CSS-классу. На сервере сброс до нуля понимает и форматы «(3)», «3 шт.» |
| Остаток в карточке | Строка остатка запрашивается заново при каждом просмотре страницы товара и каталога |
| Мини-корзина | Блок целиком обновляется через фрагменты WooCommerce |
| Цены, зависящие от валюты или группы | Необязательный режим «без кэша» для таких страниц |
Все настройки магазина вынесены на отдельную вкладку «WooCommerce». Классы элементов можно вводить без точки, например cart-count.
Многоязычность
Кэш ведётся отдельно по каждому языку, поэтому посетитель с английской версией не получит кэш русской и наоборот. Плагин SDWSKi Cache совместим с плагинами мультиязычности. В первую очередь 100% гарантирована совместимость с плагином ИИ-перевода SDWSKi Translate.
Отказоустойчивость
- Откат при сбое оптимизации. Callback output buffer защищён: если минификация или объединение файлов завершились ошибкой, отдаётся исходная страница.
- Drop-in можно удалить в любой момент. Тогда WordPress просто продолжает работать как обычно, это сказано в самом заголовке файла.
- Статус-страница Turbo показывает по пунктам, всё ли настроено: drop-in, права,
.htaccess, доступность brotli. - Безопасное удаление. Плагин не удаляет общие данные, пока на сайте остаётся другая копия движка.
Что ещё есть внутри
Предзагрузка кэша по расписанию через WP-Cron, минификация HTML/CSS/JS, объединение файлов, отложенная загрузка изображений, правила исключений, очистка кэша конкретных страниц, настройки для Nginx и Varnish, интеграции с CDN, браузерное кэширование, отключение emoji, WP-CLI. Интерфейс и подробная вкладка «Инструкция» переведены на русский.
Стек
PHP, WordPress Plugin API (хуки, WP-Cron, output buffering, drop-in advanced-cache.php), правила Apache .htaccess, JavaScript и CSS для админ-интерфейса и «живых» элементов магазина, gettext (.pot, .po, .mo) для локализации.
Установка
- Скопируйте папку
sdwski-cacheв/wp-content/plugins/и активируйте плагин. - В меню «SDWSKi Cache» включите «Cache System» и сохраните.
- Откройте «Настройки → SDWSKi Cache: Turbo» и убедитесь, что все пункты статуса зелёные.
- Проверьте результат: откройте страницу в приватном окне и найдите заголовок
X-ruzi-Turbo: HIT.
История версий
- 1.5.3-turbo.10 — отдельная вкладка WooCommerce, «живой» остаток, «живая» мини-корзина.
- 1.5.3-turbo.9 — защита корзины и остатков теперь всегда включена при активном WooCommerce, очистка кэша при любых изменениях товара и заказа, максимальный возраст кэша 3 часа.
- 1.5.3-turbo.8 — счётчик корзины подставляется скриптом, исправлено сохранение настроек режима магазина.
- 1.5.3-turbo.2 — защита от конфликта с оригинальным плагином, собственная папка, вкладка «Инструкция».
- 1.5.3-turbo.1 — режим магазина, drop-in, предсжатые страницы, ETag и 304, новый интерфейс, удалена реклама.
Лицензия и происхождение
Проект распространяется по GPLv2 или новее. Он основан на открытом GPL-плагине страничного кэша: исходный код принадлежит его авторам, а мои изменения и дополнения оформлены отдельно и описаны выше.