Сделайте WordPress WP-API быстрее, не загружая темы и плагины

Я хотел бы делать запросы к API WordPress намного быстрее. Мой API реализован в плагине (используя register_rest_route для регистрации моих маршрутов). Однако, поскольку это плагин, все загружается вместе с ним (дочерняя тема и тема), и в основном запрос к этому API занимает полсекунды из-за загрузки всех этих бесполезных частей.

Разве WordPress API не может быть использован по-другому? Так как большинство плагинов, использующих WP-API, не требуют загрузки других плагинов, тем более темы … Я не понимаю, как они могли пропустить это.

Есть какой-либо способ сделать это?

5

Решение

Да, это возможно. В одном из моих плагинов, где мне нужно минимальное ядро ​​WordPress (БД без плагинов & темы) вот что я делаю:

<?php

define('SHORTINIT', true);  // load minimal WordPress

require_once PATH_TO_WORDPRESS . '/wp-load.php'; // WordPress loader

// use $wpdb here, no plugins or themes were loaded

PATH_TO_WORDPRESS постоянная я помирилась; вам просто нужно указать на правильный путь. Например, в плагинах это может выглядеть так:

require_once dirname(__FILE__) . '/../../../wp-load.php'; // backwards 'plugin-dir/plugins/wp-content'

настройка SHORTINIT в true конечно, немного помогает производительности.

С WP_DEBUG отключено, время, необходимое для начальной загрузки WordPress:

  • Без SHORTINIT: ~ 0,045 секунд
  • С SHORTINIT: ~ 0,0015 секунд

Если это для вашего собственного сайта, где вам требуется производительность, вы, вероятно, можете немного увеличить ее, включив OpCache (например, APC или PHP OpCache в последних версиях).

Но я считаю, что 2 строки кода выше, чтобы определить SHORTINIT и требуют wp-load.php это то, что вы ищете.

Для пояснения, этот файл является частью плагина, но он вызывается независимо от самого WordPress (через Ajax и напрямую). Он никогда не включается и не используется другими частями плагина или самого WP.

РЕДАКТИРОВАТЬ: Поскольку OP на самом деле касается WP-API, а не WordPress в целом, я добавляю это, чтобы ответить на реальный вопрос. Я оставлю оригинальное содержание ответа на случай, если оно может помочь кому-то еще.

Я провел дальнейшее тестирование с использованием WP API и, как сказал @David в своем ответе, проблема, вероятно, в другом.

Я загрузил 12 плагинов в дополнение к остальному API, несколько довольно «больших» плагинов, и в моей локальной установке установлено около 25 тем (одна активная, конечно). Я редактировал WordPress ‘ index.php файл и используется microtime(true) записывать, когда все началось, а затем отредактировать один из контроллеров REST, чтобы вычислить, сколько времени прошло от начала до достижения конечной точки API.

Результат в моей системе постоянно 0.04620.0513 секунд (нет PHP OpCache и никакой другой загрузки системы). Таким образом, кажется, что начальная загрузка всего WordPress мало влияет на производительность.

Если запросы занимают полсекунды, узкое место находится в другом месте, и вырезание плагинов и тем будет иметь минимальное влияние. По крайней мере, это то, что я нашел.

8

Другие решения

Я думаю, что вы можете сосредоточиться не на том вопросе.

Загрузка php файлов не так медленна, как чтение из вашей базы данных, и это, вероятно, будет вашим временем загрузки 500 мс. На самом деле вы должны посмотреть на это в любом случае (кеш-параметры wp и т. Д.), Но я предлагаю вам в отношении API-интерфейса кешировать вывод при помощи mu-plugin. Используя выход, мы можем загрузить вывод из файла и мгновенно обслужить его.

Наш метод:
1. Создайте папку с именем mu-plugins в папке wp-content (возможно, уже там)

  1. создать файл с именем api-cache.php

  2. введите этот код в свой файл:

    function get_api_cache(){
    
    //dont run if we are calling to cache the file (see later in the code)
    if( isset($_GET['cachecall']) && $_GET['cachecall'] === true)
    return;
    
    $url = "$_SERVER[REQUEST_URI]";
    
    //do a little error checking
    
    $uri= explode('/',$url);
    
    //we have a array (1st key is blank)
    if( $uri[1] !== 'wp-json' || $uri[2] !== 'wp' || $uri[3] !== 'v2'){
    return;
    }
    
    //lock down the possible endpoints we dont want idiots playing with this...
    $allowed_endpoints= array(
    'posts'
    );
    
    $endpoint= array_pop($uri); // not sure if this is valid or not, is there more structure to some api calls?
    
    if( !in_array( $endpoint, $allowed_endpoints) ){
    return;
    }
    
    //ok reasonably confident its a api call...
    
    $cache_folder= get_stylesheet_directory().'/api_cache/';
    
    // prob best if not within php server but to get you going
    if(! file_exists ( $cache_folder ) ){
    mkdir($cache_folder); //warning 777!!
    }/*
    * Need to choose a method of control for your cached json files
    * you could clear out the folder on update post/ taxonomies etc
    * or cron clear out hourly/weekly whatever freq you want
    */if( file_exists($cache_folder.$endpoint.'.json') ){
    $json= file_get_contents($cache_folder.$endpoint.'.json');
    header('Content-Type: application/json');
    echo $json;
    exit;// we need nothing else from php exit
    } else {
    //make sure there will be no errors etc..
    $ch = curl_init();
    $url= "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]?cachecall=true";
    $timeout= 5;
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    $json = curl_exec($ch);
    curl_close($ch);
    file_put_contents($cache_folder.$endpoint.'.json', $json);
    }
    
    }
    
    get_api_cache();
    

Теперь вы должны заметить значительную разницу во времени загрузки при второй загрузке (это первый раз, когда она кэширует выходные данные).

Несколько заявлений об отказе:

  1. вы должны прочитать комментарии в коде
  2. Вам нужен завиток
  3. Вы должны знать, что папка кэша — 777, я настоятельно рекомендую вам убрать это из папки вашей темы и, предпочтительно, за пределы ваших http-доступных файлов.
  4. Не было перехвата всех ловушек для захвата данных, которые должны быть кэшированы, поэтому я использовал curl для захвата контента, это может измениться в будущем, и фильтр / ловушка немного улучшит время обработки при создании файла кэша.
  5. Я не включил метод обновления файлов кэша. Вам нужно определиться с тем, как часто вы хотите обновлять сайт, который получает много постов в день и много посещений, вы можете сделать работу cron просто удалить файлы (например, 3 раза в день, ежечасно, каждые 10 минут). и т. д. — каков разумный компромисс во времени обновления?) или добавьте хук для сохранения поста, чтобы он обновлялся только при изменении ваших постов и т. д.
  6. добавьте свои конечные точки в массив для них (вы можете удалить оператор if, чтобы разрешить все конечные точки, но тогда у вас может возникнуть ситуация, когда 404s кэшируются!)
2

Вы должны попробовать этот. Это плагин, который позволяет включать / отключать определенные плагины для пост-типов, страниц и других обстоятельств.

Для части темы, если бы вы ее написали, было бы легко добавить что-то в файл function.php, чтобы предотвратить прикрепление каких-либо хуков или фильтров в случае запроса API.

Как sidenote, не могли бы вы запросить де БД напрямую?

0

Извините за мой плохой английский, если это полезно для вас.

Поместите папку плагина в корневую установку WordPress.

/public_html/my-plugin/my-plugin.php

and include wordpress main file.

require dirname( dirname( __FILE__ ) ).'/wp-load.php';

Или в папке плагина прямой доступ

/public_html/wp-content/plugins/my-plugin/my-plugin.php
require_once dirname(__FILE__) . '/../../../wp-load.php';

Перед проверкой файл wp-load.php включен правильно и работает.

Файл wp-settings.php загружает все ядро, плагины и файлы тем. WordPress загружает первые файлы mu-plugins (wp-content / mu-plugins /) и предоставляет хук после действия muplugins_loaded. Запустите это действие, чтобы выйти из других загруженных файлов. Вы также можете найти, какой хук действия предоставляется, прежде чем muplugins_loaded и остановить другие файлы и выполнение скрипта.

Если определить константу SHORTINIT, прежде чем включать wp-load.php его включает
некоторые файлы предоставляют БД, плагин или основные функции. Когда мы хотим больше загружать файлы ядра, а не просто хотим загружать плагины и файлы тем таким способом, мы нашли решение.

// file my-plugin.php
//call before include file wp-load.php
global $wp_filter;
$wp_filter = array(
// pass wp hook where to want exit extra wp loaded
'muplugins_loaded' => array(
// prority
1 => array(
// callback function register
'wp_extra_loaded_exit' => array(

'function' => 'wp_extra_loaded_exit',

'accepted_args' => 1

)
)
)
);function wp_extra_loaded_exit(){
exit;

}
require dirname( dirname( __FILE__ ) ).'/wp-load.php';
// plugin code here.

Мы проверяем muplugins_loaded ловушка определить WordPress рано, вы также можете найти, какой ловушка определить раньше muplugins_loaded затем остановите эту точку после загрузки файлов WordPress. —

Если вы хотите протестировать ваш скрипт, откройте файл wp-settings.php и найдите строку muplugins_loaded, а затем проверьте команду echo.

echo "Wordpress loaded in this point before";

do_action( 'muplugins_loaded' );

echo "After this wordpress not loading"; // Output fail bcz we exit
0
По вопросам рекламы [email protected]