WordPress: разработка сайтов, интернет-магазинов и кастомных решений
Клиент приходит с готовым сайтом на WordPress — и первое, что вижу в DevTools: 47 активных плагинов, страница весит 6.8MB, Time to First Byte 2.4s, а в консоли пять конфликтующих версий jQuery. Это не редкость. Это стандарт «доделанного» сайта, который вырос из шаблона в нечто живое, но неуправляемое.
WordPress занимает 43% рынка CMS — не потому что он идеален, а потому что он предсказуем, обширно задокументирован и имеет экосистему плагинов для любой задачи. Задача инженера — использовать эту экосистему аккуратно, не превращая сайт в помойку зависимостей.
Где чаще всего ломается WordPress в продакшене
Три сценария, которые встречаю чаще всего:
Блокировка рендеринга из-за плагинов. Plugin A загружает jQuery 3.6, Plugin B — jQuery 1.12, тема — свой jQuery Migrate. В итоге wp_enqueue_scripts отдаёт три разных версии библиотеки, рендеринг страницы блокируется на 800ms ещё до начала парсинга основного контента. Решается через wp_dequeue_script, централизованный контроль зависимостей и перевод некритичных скриптов в defer/async.
N+1 в кастомных запросах. Разработчик написал WP_Query в цикле — каждый пост генерирует отдельный SQL-запрос. На странице с 20 постами это 21+ запрос к базе. MySQL начинает тупить, сервер греется. Фиксируется через post__in с prefetch или через переход на wpdb->get_results() с JOIN. Query Monitor — первый инструмент для диагностики.
WooCommerce под нагрузкой. Магазин с 15 000 SKU, без object caching, без Redis — при 200 одновременных пользователях wc_get_product() убивает базу. Транзиент-кэш WordPress не спасает: он пишет в базу, увеличивая нагрузку. Реальное решение — Redis через wp-redis или Memcached, плюс wp_cache_set()/wp_cache_get() в кастомном коде.
Стек и подходы в нашей работе
Разработка тем. Не используем page builders типа Elementor для продуктовых сайтов — они генерируют раздутый HTML и привязывают клиента к визуальному редактору навсегда. Вместо этого: кастомная тема на базе _s (underscores) или блочная тема для Full Site Editing, Tailwind CSS через Vite, TypeScript для любого сложного JS.
Gutenberg и блочная разработка. Начиная с WordPress 5.0 Gutenberg — это не редактор, это платформа. Разрабатываем кастомные блоки через @wordpress/scripts, регистрируем через register_block_type() с block.json. Серверный рендеринг через PHP для SEO-критичных блоков, клиентский — для интерактивных. Inner Blocks для составных компонентов.
REST API и headless. WordPress как headless CMS через WP REST API v2 или WPGraphQL. Типичная схема: WordPress на поддомене cms.example.com, Next.js фронтенд на основном домене. ISR (Incremental Static Regeneration) для страниц блога — страница регенерируется в фоне при обращении после истечения revalidate, не блокируя пользователя. Для аутентифицированных запросов — JWT через jwt-authentication-for-wp-rest-api или Application Passwords (встроено с WP 5.6).
WooCommerce. Расширяем через хуки и фильтры — никогда не правим core-файлы. Кастомные типы продуктов через WC_Product extension. Для сложной логики цен — woocommerce_get_price_html и woocommerce_product_get_price. Payment gateways пишем с нуля, наследуя от WC_Payment_Gateway. Интеграция с 1С — через CommerceML или кастомный REST endpoint.
Производительность. Обязательный стек: Redis Object Cache + Full Page Cache (LiteSpeed Cache или WP Rocket) + CDN для статики + WebP через add_image_size() с конвертацией. Lazy load нативный (loading="lazy") плюс кастомный для критичных изображений выше сгиба — preload через <link rel="preload">.
Кейс: WooCommerce-магазин, LCP 9s → 1.8s
Магазин электроники, 40 000 SKU, WooCommerce + кастомная тема. PageSpeed Insights: LCP 9.2s, CLS 0.41, INP 680ms.
Диагноз:
- Hero-изображение 3.8MB JPEG, не оптимизированное, без
srcset - 23 плагина загружали JS/CSS на каждой странице, включая страницы продуктов
-
wc_get_product()вызывался 60 раз на странице категории без кэширования - Шрифты загружались через Google Fonts (дополнительный DNS lookup)
Что сделали:
- Hero — WebP 180KB,
<img fetchpriority="high" decoding="async">,srcsetдля 3 breakpoints - Условная загрузка плагинов через
is_product(),is_cart(),is_checkout()— убрали 80% лишнего JS - Redis Object Cache,
WC_Productprefetch черезwc_get_products()сinclude - Шрифты — self-hosted через
@font-face,font-display: swap - CLS победили через
aspect-ratioна всех product card images
Результат: LCP 1.8s, CLS 0.04, INP 140ms. Core Web Vitals — зелёные.
Процесс работы
Аудит и аналитика. Для нового проекта — анализ существующей кодовой базы (если есть), конкурентов, технических требований. Для нового сайта — аналитика по семантике, UX-прототипирование.
Архитектура. Решаем: монолитный WordPress или headless. Определяем типы данных: Custom Post Types, Custom Fields (ACF или нативные register_meta()), таксономии.
Разработка. Local by Flywheel или Docker (nginx + php-fpm + MariaDB) для локальной среды. Git с хуками pre-commit для PHP CS Fixer и ESLint. Деплой через WP-CLI + SSH или через Buddy.works CI/CD.
Тестирование. PHP Unit для кастомных плагинов. Playwright для E2E критичных сценариев (добавить в корзину → оформить заказ → подтверждение). Lighthouse CI в пайплайне — падаем, если Performance Score < 85.
Деплой и поддержка. Staging через WP Stagecoach или ручной клон. Мониторинг — UptimeRobot + Sentry для PHP ошибок. Обновления плагинов — через WP-CLI в тестовой среде сначала.
Ориентиры по срокам
| Тип проекта | Срок |
|---|---|
| Лендинг на кастомной теме | 2–3 недели |
| Корпоративный сайт (10–30 страниц) | 4–8 недель |
| WooCommerce-магазин (базовый) | 6–10 недель |
| WooCommerce + кастомная логика + интеграции | 3–6 месяцев |
| Headless WordPress + Next.js | 8–16 недель |
Стоимость рассчитывается индивидуально после аудита требований.
Типичные ошибки при разработке на WordPress
Прямое редактирование файлов темы. При обновлении темы все изменения теряются. Всегда — дочерняя тема или полностью кастомная.
update_post_meta() в цикле. Каждый вызов — отдельный UPDATE. Для массовых операций — $wpdb->update() или update_metadata_by_mid().
Отключённый WP_DEBUG в разработке. Скрытые PHP Notice засоряют error log и часто указывают на реальные проблемы в логике.
Хранение медиа в Git. wp-content/uploads — в .gitignore, синхронизация через WP-CLI media import или rsync.
Нет лимита на WP_Query. posts_per_page => -1 на странице с тысячами записей — гарантированный таймаут.







