Ajax занимает в 10 раз больше времени, чем должен/мог бы

9 февр. 2012 г., 21:45:53
Просмотры: 25.3K
Голосов: 55

Я только что столкнулся с первой серьезной проблемой в WordPress, и как человеку, который любит работать с Ajax, это кажется существенным.

У меня есть Ajax-запрос, который выполняется 1.5 секунды при использовании Ajax API WordPress.

Если я беру точно такой же код и запускаю его с помощью собственного скрипта (без WordPress), Ajax-запрос выполняется всего за 150 миллисекунд. Это не преувеличение

Если посмотреть на самый первый комментарий в http://wp.smashingmagazine.com/2011/10/18/how-to-use-ajax-in-wordpress/ и последующее обсуждение, вы увидите, что эта медлительность вызвана тем, что при каждом запросе загружается весь WordPress...

Я надеюсь, что существует решение, которое позволит выполнять Ajax-запросы без загрузки всего WordPress.

Каков ваш опыт по ускорению Ajax-запросов в WordPress?

2
Комментарии

Интересно, учитывают ли популярные плагины кеширования эту ситуацию.

Raphael Raphael
9 февр. 2012 г. 23:12:18

@Raphael, я тоже об этом подумал, но не нашел упоминаний. Было бы ОТЛИЧНО, если они это поддерживают

Mike Mike
9 февр. 2012 г. 23:25:56
Все ответы на вопрос 2
12
63

Да, это неприятная проблема — для полной загрузки окружения WordPress требуется значительное время.

Мне понадобилась гораздо лучшая производительность (для очень динамичного поиска с инкрементальным выводом результатов), и вот что я сделал:

  1. Создал пользовательский файл в качестве обработчика Ajax.
  2. Использовал константу SHORTINIT для ограниченной загрузки ядра WordPress.
  3. Очень избирательно подгружал только те части ядра, которые действительно нужны для задачи.

Это обеспечивает сильно ограниченное окружение, но производительность становится значительно лучше, при этом сохраняется разумная степень совместимости с WordPress (начиная с $wpdb).

Вот начало моего загрузочного файла — выглядит не идеально, но работает для конкретных нужд:

<?php

ini_set('html_errors', 0);
define('SHORTINIT', true);

require '../../../../wp-load.php';
require( ABSPATH . WPINC . '/formatting.php' );
require( ABSPATH . WPINC . '/meta.php' );
require( ABSPATH . WPINC . '/post.php' );
wp_plugin_directory_constants();

// здесь будет основной код
9 февр. 2012 г. 22:12:09
Комментарии

Что вы подразумеваете под константой SHORTINIT? Можете привести примеры? Я предполагаю, что мне нужно будет настроить собственные обработчики с разной степенью загрузки WP в зависимости от потребностей запроса, но хотелось бы увидеть примеры, которые вы создали.

Mike Mike
9 февр. 2012 г. 22:20:28

@Mike это не широко известно, но концепция очень проста - если константа SHORTINIT установлена, WP не будет загружать большую часть ядра (нет большинства API/функций, нет плагинов, нет темы). Я добавлю код для ответа.

Rarst Rarst
9 февр. 2012 г. 23:38:20

Выглядит нормально. Мне просто не нравится факт, что приходится использовать require '../../../../wp-load.php'; это делает решение довольно кастомным. Также беспокоит, насколько легко можно подтянуть именно те ресурсы, которые "нужны", потому что по моему опыту WordPress не очень модульный.

Mike Mike
10 февр. 2012 г. 19:47:00

@Mike верно, но даже с проблемами это намного лучше, чем конечная точка, которая вообще ничего не знает о WP. Это можно (и нужно) еще улучшить, но на данный момент для меня это не срочная задача.

Rarst Rarst
10 февр. 2012 г. 21:32:19

Есть ли какие-нибудь методы определения местоположения wp-load.php изнутри WordPress? Например, могу ли я записать статический файл с установленным путем как переменную внутри него при загрузке плагина, а затем включить этот файл в автономный файл ответа Ajax?

hereswhatidid hereswhatidid
20 дек. 2012 г. 20:26:41

@hereswhatidid да, это один из вариантов, вы можете использовать, например, get_included_files() PHP. Однако обратите внимание, что запись в директорию плагина — не самая лучшая практика, обычно записи в файловую систему должны производиться только в директорию контента. Это та проблема, которую не так сложно настроить для себя, но довольно сложно создать решение, подходящее для публичного кода.

Rarst Rarst
20 дек. 2012 г. 20:40:10

@Rarst, вместо require '../../../../wp-load.php'; я думаю, что лучше использовать что-то вроде: $dir = explode ( 'wp-content', dirname(__FILE__) ); и затем require $dir[0] . 'wp_load.php'? Я считаю, что это более гибко и может использоваться повсеместно в теме или плагине

gmazzap gmazzap
23 июл. 2013 г. 14:43:39

@G.M. папка content может быть свободно перемещена, это ошибочное предположение, что код выполняется внутри корневой директории. Как указано выше - это сложно обработать универсальным способом.

Rarst Rarst
23 июл. 2013 г. 15:34:27

@Rarst, конечно, папка content может быть перемещена, но если это так, ваше решение тоже может не сработать, или я ошибаюсь? Если в моем плагине (или теме) у меня есть файл options.php, где я определяю define('WPCONTENTROOTFOLDER', 'wp-content') и затем $dir = explode ( WPCONTENTROOTFOLDER, dirname(__FILE__) ), это будет работать в 90% случаев, а для остальных я напишу в документации плагина, что нужно изменить, если папка content перемещена. Например, я могу реализовать другую константу 'FULLWPCONTENTFOLDER', обычно пустую, но если она задана, плагин будет использовать её.

gmazzap gmazzap
23 июл. 2013 г. 18:02:57

@G.M. моё решение специфично для моей установки, оно не предназначено для распространяемого кода. Ваш код просто захардкожен с другими (более общими относительно, я согласен) предположениями, но лично я не считаю, что он соответствует уровню распространяемого кода.

Rarst Rarst
23 июл. 2013 г. 18:57:09

@Rarst (последнее, честно) Да, возможно мой код не распространяемый (конечно не для репозитория WP и/или большой аудитории), но я считаю его переиспользуемым кодом, хотя бы для себя: на данный момент у меня более 20 клиентских установок WP онлайн, и во всех есть плагины, разработанные мной, поэтому писать легко переиспользуемый код жизненно необходимо для меня, даже если это не распространяемый код.

gmazzap gmazzap
23 июл. 2013 г. 20:16:31

Я использовал форкнутую (приватную) версию этого плагина с GitHub: http://github.com/EkAndreas/ajaxflow/

Austin Passy Austin Passy
10 мар. 2016 г. 22:18:41
Показать остальные 7 комментариев
0

Я нашел это, и это ускорило мой ajax.

function my_deregister_heartbeat() {
    global $pagenow;

    if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow ) {
         wp_deregister_script('heartbeat');
         wp_register_script('heartbeat', false);
     }
}
add_action( 'admin_enqueue_scripts', 'my_deregister_heartbeat' );
13 июл. 2014 г. 16:20:31