Ajax durează de 10 ori mai mult decât ar trebui/putea
Tocmai m-am lovit de prima mea problemă serioasă cu WordPress și pentru cineva care apreciază Ajax, aceasta este una majoră.
Am o cerere Ajax care durează 1.5 secunde pentru a se finaliza în timp ce folosesc API-ul Ajax.
Dacă iau exact același cod și îl rulez cu un script personalizat (fără WordPress), cererea Ajax durează doar 150 milisecunde. Aceasta nu este o exagerare
Dacă te uiți la primul comentariu de pe http://wp.smashingmagazine.com/2011/10/18/how-to-use-ajax-in-wordpress/ și la conversația care urmează, vei vedea că această încetineală este cauzată de faptul că la fiecare cerere, tot WordPress-ul este încărcat...
Sper că există o soluție care va face posibilă executarea cererilor Ajax fără a încărca tot WordPress-ul.
Care sunt experiențele voastre în ceea ce privește accelerarea cererilor Ajax în WordPress?

Da, aceasta este o problemă neplăcută - pentru a avea un mediu WordPress complet, trebuie să petreci o perioadă considerabilă de timp încărcându-l.
Am avut nevoie de o performanță mult mai bună (pentru o funcționalitate de căutare incrementală foarte dinamică) la locul de muncă și soluția pe care am ales-o a fost:
- Un fișier personalizat ca handler Ajax.
- Constanta SHORTINIT pentru încărcarea limitată a nucleului WordPress.
- Încărcarea foarte selectivă a părților din nucleu, doar pe cele necesare pentru sarcină.
Aceasta oferă un mediu foarte limitat, dar performanța este mult, mult mai bună și se păstrează un grad rezonabil de compatibilitate cu WordPress (începând cu $wpdb
).
Iată începutul fișierului meu de încărcare, nu este foarte elegant dar funcționează pentru nevoile specifice:
<?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();
// aici se adaugă logica specifică

Ce înseamnă constanta SHORTINIT? Poți oferi exemple? Îmi imaginez că va trebui să configurez propriile mele handler-uri cu diferite grade de încărcare a WP, în funcție de nevoile cererii, dar aș dori să văd câteva exemple pe care le-ai creat.

@Mike nu este foarte cunoscută, dar conceptul este foarte simplu - dacă constanta SHORTINIT
este setată WP nu va încărca majoritatea componentelor de bază (nici majoritatea API-urilor/funcțiilor, nici plugin-uri, nici teme). Voi adăuga niște cod ca răspuns.

Pare ok. Nu-mi place doar faptul că trebuie să folosim require '../../../../wp-load.php'; asta face lucrurile destul de personalizate. De asemenea, mă îngrijorează cât de ușor este să incluzi resursele de care "ai nevoie", pentru că din experiența mea WordPress nu este foarte modular.

@Mike corect, dar chiar și cu probleme, este mult mai bine decât un endpoint care nu are nicio idee despre WP. Acest lucru poate (și ar trebui) să fie îmbunătățit în continuare, dar nu este o sarcină urgentă pentru mine în acest moment.

Există vreo metodă de a detecta locația fișierului wp-load.php din interiorul WordPress? De exemplu, aș putea scrie un fișier static cu calea setată ca variabilă în el la încărcarea pluginului, apoi să includ acel fișier în fișierul independent de răspuns Ajax?

@hereswhatidid da, aceasta este una dintre opțiuni, ai putea folosi de exemplu get_included_files()
din PHP. Totuși, reține că scrierea în directorul pluginului nu este o practică prea bună, de obicei scrierile pe sistemul de fișiere ar trebui să se facă doar în directorul de conținut. Aceasta este genul de problemă care nu este atât de dificil de configurat pentru tine, dar este destul de greu să produci o soluție care este potrivită pentru cod public.

@Rarst, în loc de require '../../../../wp-load.php';
cred că este mai bine să folosești ceva de genul:$dir = explode ( 'wp-content', dirname(__FILE__) );
și apoi require $dir[0] . 'wp_load.php'
? Cred că este mai flexibil și poate fi folosit oriunde în temă sau plugin

@G.M. directorul de conținut poate fi relocat liber, este o presupunere greșită că codul rulează din interiorul directorului principal. Ca mai sus - acest lucru este dificil de gestionat într-un mod generic.

@Rarst, cu siguranță directorul de conținut poate fi relocat, dar dacă da, soluția ta poate de asemenea să eșueze, sau greșesc? Dacă în plugin-ul meu (sau temă) am un fișier options.php
unde define('WPCONTENTROOTFOLDER', 'wp-content')
și apoi $dir = explode ( WPCONTENTROOTFOLDER, dirname(__FILE__) )
acest lucru va funcționa în 90% din cazuri, iar pentru restul scriu în documentația plugin-ului meu ce schimbare să facă dacă directorul de conținut este mutat. De exemplu, pot implementa o altă constantă 'FULLWPCONTENTFOLDER', în mod normal goală, dar dacă este setată, plugin-ul va folosi aceasta în schimb.

@G.M. soluția mea este specifică instalării mele, nu este destinată codului distribuit. Codul tău doar hardcodează o presupunere diferită (mai generică relativ, sunt de acord), dar personal nu cred că este la nivel de cod distribuit nici el

@Rarst (ultimul lucru, jur) Da, probabil al meu nu este cod distribuibil (cu siguranță nu în repository-ul WP și/sau pentru o audiență largă), dar cred că este cod reutilizabil, chiar dacă doar pentru mine: în prezent am peste 20 de instalări WordPress pentru clienți online și în toate acestea există plugin-uri dezvoltate de mine, așa că scrierea de cod ușor de reutilizat este vitală pentru mine chiar dacă nu este cod distribuit.

Am folosit o versiune fork (privată) a acestui plugin găsită pe GitHub: http://github.com/EkAndreas/ajaxflow/

Am găsit acest cod și mi-a accelerat cererile 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' );
