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, без об'єктного кешування, без 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 розширення. Для складної логіки цін — 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() з конвертацією. Нативний ледиве завантажувальник (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 на сторінці з тисячами записів — гарантований timeout.







