☰
WORDPRESS / PRACTICE

Оптимізація відповідей WordPress REST API: як не віддавати зайві дані

Оптимізація відповідей WordPress REST API: як не віддавати зайві дані

WordPress REST API за замовчуванням може повертати значно більше даних, ніж потрібно фронтенду: повний вміст запису, анонс, метадані, посилання, автора та інші службові поля. Для одного запису це не завжди критично, але під час завантаження колекції зайві дані швидко збільшують розмір JSON-відповіді та кількість роботи на сервері.

Оптимізація не потребує змін у WordPress Core. У більшості випадків достатньо правильно формувати запити: обмежувати кількість записів через per_page, вибирати потрібні поля за допомогою _fields і не використовувати _embed без реальної потреби.

Чому зайві поля REST API створюють проблему

Запит до стандартного endpoint, наприклад /wp-json/wp/v2/posts, повертає об’єкт запису з багатьма властивостями. Для картки у списку новин фронтенду часто потрібні лише ідентифікатор, заголовок, дата, slug і посилання. Повний content або excerpt у такому сценарії не використовується, але все одно потрапляє до відповіді.

Чим більше записів повертає один запит, тим більшим стає JSON. Браузеру потрібно завантажити й розібрати ці дані, а PHP — підготувати відповідь. Додаткові витрати особливо помітні для сайтів із великими текстами, складними метаданими або повільним сервером.

Це не означає, що кожна відповідь за замовчуванням є критично повільною. Проблема виникає тоді, коли великий обсяг даних регулярно передається для списків, пошуку, мобільних клієнтів або безголових WordPress-проєктів.

  • зростає розмір відповіді та час її передавання;
  • фронтенд обробляє дані, які не використовує;
  • збільшується навантаження на PHP і проміжні кеші;
  • мобільні користувачі витрачають більше трафіку.

Обмежуйте набір полів через _fields

Параметр _fields дає змогу попросити REST API повернути лише необхідні властивості. Це найпростіший крок для оптимізації стандартних endpoint’ів. Поля вказують через кому без пробілів.

Наприклад, для списку записів, де потрібні лише базові дані, достатньо такого запиту:

/wp-json/wp/v2/posts?per_page=10&_fields=id,slug,date,title,link

Як вибирати поля для вкладених об’єктів

Деякі властивості REST API є об’єктами. Наприклад, title зазвичай містить окреме поле rendered. Якщо фронтенду потрібен лише текст заголовка, можна вказати вкладене поле, а не весь об’єкт:

  • id — ідентифікатор запису;
  • slug — частина URL;
  • date — дата публікації;
  • title.rendered — відображуваний заголовок;
  • link — готове посилання на запис.
/wp-json/wp/v2/posts?per_page=10&_fields=id,slug,date,title.rendered,link

Не вказуйте поля навмання

Перед скороченням відповіді перевірте, які властивості реально використовує фронтенд. Якщо прибрати потрібне поле, компонент може перестати відображати частину даних. Після зміни запиту перевірте не лише HTTP-відповідь, а й роботу карток, пагінації, сортування та посилань.

Також варто пам’ятати, що _fields скорочує результат для клієнта, але не перетворює REST API на повністю кастомний SQL-запит. WordPress усе одно готує відповідь відповідно до логіки endpoint’а. Тому фільтрацію полів слід поєднувати з розумною кількістю елементів у запиті.

Використовуйте per_page і коротку пагінацію

Для колекцій не варто завантажувати всі записи одним запитом. Параметр per_page задає кількість елементів на сторінці, а page — номер сторінки. Короткі сторінки зменшують обсяг відповіді та дають змогу фронтенду показувати контент поступово.

Практичний варіант для списку — запит на 10 або іншу кількість записів, яку справді може одночасно показати інтерфейс:

  • використовуйте per_page відповідно до розміру списку на екрані;
  • передавайте page для наступних порцій даних;
  • не збільшуйте per_page лише для зменшення кількості HTTP-запитів;
  • обробляйте ситуацію, коли сторінка виходить за межі доступних записів.
/wp-json/wp/v2/posts?per_page=10&page=2&_fields=id,slug,date,title.rendered,link

Як визначити кількість сторінок

У відповідях колекцій WordPress зазвичай передає заголовки з інформацією про загальну кількість записів і сторінок. Фронтенд може використовувати їх для кнопки «Показати ще», класичної пагінації або нескінченного прокручування.

Не покладайтеся лише на кількість елементів у поточній відповіді: остання сторінка може містити менше записів, ніж per_page. Перевіряйте статус відповіді та коректно обробляйте помилки доступу або некоректний номер сторінки.

Не додавайте _embed без потреби

Параметр _embed використовується, щоб включити до відповіді пов’язані ресурси: автора, featured image, терміни таксономій та інші об’єкти, які WordPress може отримати для запису. Це зручно, коли фронтенду справді потрібні такі дані в одному запиті, але для списків параметр може помітно збільшити відповідь.

Якщо картка показує лише заголовок, дату і посилання, _embed не потрібен. Його додавання «про запас» часто призводить до передачі вкладених об’єктів, які ніхто не використовує.

  • не використовуйте _embed у кожному запиті автоматично;
  • додавайте його лише для сценаріїв із пов’язаними ресурсами;
  • разом із _embed перевіряйте, чи можна обмежити поля через _fields;
  • порівнюйте розмір відповіді з _embed і без нього.
/wp-json/wp/v2/posts?per_page=10&_embed&_fields=id,slug,title.rendered,_embedded

Коли _embed виправданий

Параметр може бути доречним для новинної картки, якій одночасно потрібні зображення, ім’я автора і категорія. Його користь потрібно оцінювати в конкретному сценарії: іноді один запит із вбудованими даними простіший і швидший за кілька окремих запитів, а іноді він створює надмірний обсяг JSON.

Для точного рішення порівняйте фактичні відповіді в інструментах розробника браузера або через командний рядок. Важливі не лише кілобайти, а й час відповіді, кількість запитів та обсяг даних, який реально читає фронтенд.

Формуйте мінімальну відповідь у кастомних endpoint’ах

Якщо ви створюєте власний REST endpoint, не повертайте весь об’єкт WP_Post або необроблений результат запиту. Клієнту краще віддати стабільну структуру з полями, які потрібні саме цьому сценарію.

Наприклад, endpoint для каталогу може повертати id, назву, ціну, короткий URL і зображення, але не повний контент, службові метадані та всі зв’язки об’єкта. Такий підхід спрощує контракт між бекендом і фронтендом та зменшує ризик випадково розкрити внутрішні дані.

  • визначте DTO-подібну структуру відповіді для кожного сценарію;
  • не передавайте внутрішні метаполя без необхідності;
  • нормалізуйте дати, URL і назви полів у зрозумілий формат;
  • документуйте обов’язкові та необов’язкові властивості.
register_rest_route('site/v1', '/cards', [
    'methods'  => 'GET',
    'callback' => function ($request) {
        $posts = get_posts([
            'post_type'      => 'post',
            'posts_per_page' => 10,
            'post_status'    => 'publish',
        ]);

        return array_map(function ($post) {
            return [
                'id'    => $post->ID,
                'slug'  => $post->post_name,
                'title' => get_the_title($post),
                'link'  => get_permalink($post),
            ];
        }, $posts);
    },
]);

Безпека кастомних відповідей

Мінімізація JSON не замінює перевірку дозволів. Для приватних даних або endpoint’ів, доступних лише авторизованим користувачам, окремо налаштуйте permission_callback і перевірку прав. Не слід вважати поле безпечним лише тому, що воно не відображається у звичайному інтерфейсі.

Також уникайте безпосереднього повернення об’єктів із метаданими користувачів, токенами, внутрішніми ідентифікаторами інтеграцій або іншою службовою інформацією.

Як перевірити результат оптимізації

Оптимізацію потрібно оцінювати на реальних запитах, а не лише за виглядом URL. Порівняйте стандартну та скорочену відповідь для однакової кількості записів і перевірте, чи отримує фронтенд усі необхідні дані.

Тестуйте не тільки успішний сценарій. Перевірте порожній список, останню сторінку, відсутнє зображення, довгий заголовок, помилки мережі та запит до endpoint із недостатніми правами.

  • розмір відповіді в Network у браузері;
  • час очікування та час завантаження JSON;
  • кількість елементів і коректність пагінації;
  • наявність усіх полів, які читає JavaScript;
  • поведінку кешування та повторних запитів;
  • логи PHP і помилки REST API після змін.
curl -i 'https://example.com/wp-json/wp/v2/posts?per_page=10&_fields=id,slug,date,title.rendered,link'

Поширені помилки

Одна з типових помилок — залишити _embed у всіх запитах, навіть якщо він був потрібен лише на сторінці деталей. Інша — встановити надто великий per_page, щоб «зменшити» кількість запитів. У результаті один запит стає важким для сервера й браузера.

Також не варто додавати _fields, не перевіривши вкладені структури. Запит може формально повертати відповідь 200, але фронтенд очікуватиме title.rendered, а отримає іншу форму даних або взагалі не отримає потрібне поле.

Поширені запитання

Чи потрібно завжди використовувати _fields у WordPress REST API?

Для великих колекцій і публічних запитів це бажана практика, особливо коли фронтенду потрібна лише частина об’єкта. Для внутрішнього одноразового запиту користь може бути меншою, але склад відповіді все одно варто контролювати.

Чи замінює _fields параметр _embed?

Ні. _fields обмежує поля відповіді, а _embed додає пов’язані ресурси. Їх можна використовувати разом, якщо фронтенду потрібні вбудовані дані, але слід перевірити, які саме властивості повертаються та чи не став JSON надто великим.

Яке значення per_page обрати?

Універсального значення немає. Орієнтуйтеся на кількість елементів, яку інтерфейс показує за один раз, розмір записів і можливості сервера. Краще кілька помірних сторінок, ніж один надмірно великий запит.

Чи скорочує _fields навантаження на PHP?

Він гарантовано скорочує дані, які формуються для відправлення клієнту, але не завжди усуває всю внутрішню роботу WordPress із підготовки об’єкта. Для максимального ефекту поєднуйте _fields із пагінацією, відмовою від непотрібного _embed і мінімальними кастомними відповідями.

Висновок

Оптимальний REST-запит WordPress має повертати не «все доступне», а лише дані для конкретного екрана або функції. Почніть із трьох кроків: обмежте per_page, перелічіть потрібні поля через _fields і приберіть _embed там, де немає пов’язаних ресурсів.

Для власних endpoint’ів формуйте мінімальну структуру відповіді та перевіряйте її в браузері, через curl і на тестових сценаріях. Це зменшує JSON, прискорює роботу фронтенду й допомагає не створювати зайве навантаження на PHP без небезпечних змін у ядрі WordPress.

← Усі матеріали WordPress