Faster Ajax For WordPress
WordPress as a nice API to handle Ajax requests but for some cases its a major overload to include the whole WordPress environment for simple things, So instead define your own light-weight version of an ajax handler:
<?php
//mimic the actual admin-ajax
define('DOING_AJAX', true);
if (!isset( $_POST['action']))
die('-1');
ini_set('html_errors', 0);
//make sure we skip most of the loading which we might not need
//http://core.trac.wordpress.org/browser/branches/3.4/wp-settings.php#L99
define('SHORTINIT', true);
//make sure you update this line
//to the relative location of the wp-load.php
require_once('../../../../../wp-load.php');
//Typical headers
header('Content-Type: text/html');
send_nosniff_header();
//Disable caching
header('Cache-Control: no-cache');
header('Pragma: no-cache');
//Include only the files and function we need
require( ABSPATH . WPINC . '/formatting.php' );
require( ABSPATH . WPINC . '/meta.php' );
require( ABSPATH . WPINC . '/post.php' );
wp_plugin_directory_constants();
//and do your stuff
But this is for very specific stuff when you know where are the functions you need are located and their dependencies, to know which files to include.
But if you don't (which is usually my case) here is a more generic version of a custom ajax handler:
<?php
//mimic the actuall admin-ajax
define('DOING_AJAX', true);
if (!isset( $_POST['action']))
die('-1');
//make sure you update this line
//to the relative location of the wp-load.php
require_once('../../../../../wp-load.php');
//Typical headers
header('Content-Type: text/html');
send_nosniff_header();
//Disable caching
header('Cache-Control: no-cache');
header('Pragma: no-cache');
Just about the same but the file inclusion is done for us.
Next we need to call the actual methods we want to invoke so:
$action = esc_attr(trim($_POST['action']));
//A bit of security
$allowed_actions = array(
'my_allow_action_1',
'my_allow_action_2',
'my_allow_action_3',
'my_allow_action_4',
'my_allow_action_5'
);
if(in_array($action, $allowed_actions)){
if(is_user_logged_in())
do_action('MY_AJAX_HANDLER_'.$action);
else
do_action('MY_AJAX_HANDLER_nopriv_'.$action);
}
else{
die('-1');
}
So altogether we get MYCUSTOMAJAX.php:
<?php
//mimic the actuall admin-ajax
define('DOING_AJAX', true);
if (!isset( $_POST['action']))
die('-1');
//make sure you update this line
//to the relative location of the wp-load.php
require_once('../../../../../wp-load.php');
//Typical headers
header('Content-Type: text/html');
send_nosniff_header();
//Disable caching
header('Cache-Control: no-cache');
header('Pragma: no-cache');
$action = esc_attr(trim($_POST['action']));
//A bit of security
$allowed_actions = array(
'my_allow_action_1',
'my_allow_action_2',
'my_allow_action_3',
'my_allow_action_4',
'my_allow_action_5'
);
if(in_array($action, $allowed_actions)){
if(is_user_logged_in())
do_action('MY_AJAX_HANDLER_'.$action);
else
do_action('MY_AJAX_HANDLER_nopriv_'.$action);
}
else{
die('-1');
}
Next we Only need to hook our callbacks to this handler like so:
//For logged in users
add_action('MY_AJAX_HANDLER_{$action_name}','function_callback_name');
//For logged out users
add_action('MY_AJAX_HANDLER_nopriv_{$action_name}','function_callback_name');
And all that is left is to simply call make your ajax request to this newly created file, like this:
jQuery(document).ready(function($){
var data={
action:'action_name',
otherData: 'otherValue'
};
$.post('http://url/to/your/MY_CUSTOM_AJAX.php', data, function(response){
alert(response);
});
});
Enjoy The speed!
Written by raz ohad
Related protips
12 Responses
Also, a GET request -when safe- is much quicker to initialize and to execute in JavaScript than a POST one.
What about benchmark to compare performance?
@jurgelenas:
Not Direct benchmarks but reports::
http://wp.smashingmagazine.com/2011/10/18/how-to-use-ajax-in-wordpress/#comment-8387
and the questions that started all of this
http://wordpress.stackexchange.com/questions/41808/ajax-takes-10x-as-long-as-it-should-could
Did a experimental and minimal test to this. Ordinary wp-ajax gave me a response time at 250ms. This approach gave me 100ms.
usual ajax request via addaction( 'wpajax_...
http://screencast.com/t/TdipqkLIM
the way author sugested
http://screencast.com/t/jW2Y76gN5v
The first number is a responce. The lower is current memory usage.
So on my site this goes down from 18 mb per ajax request to 4-5 mb depending on needed functions.
That was in reply to jurgelenas
Converted this code to a WordPress plugin...
https://github.com/EkAndreas/ajaxflow
and wordpress.org repo plugin http://wordpress.org/plugins/ajaxflow/
This can't possibly ever work, do_action won't do anything.
Assuming you know what plugins that you're using for the ajax calls, you could probably get away with something similar to this (see http://pastebin.com/13N9wh39) to exclude the loading of plugins unassociated with your ajax request.
Replacing the MY_AJAX_HANDLER_*
hook names with the regular wp_ajax_*
works fine for me, that makes the script easier to use general cases.
am getting an error
templates/ajax-handler.php 403 (Forbidden)
XHR Loaded (ajax-handler.php - 403 Forbidden - 196.57756900972163ms - 910B)
--
it was working fine on the local host, but it is not working on the live server
update: it works fine on http but not on https
Action hook not fired