Last Updated: December 27, 2018
·
27.1K
· bainternet

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!

12 Responses
Add your response

Also, a GET request -when safe- is much quicker to initialize and to execute in JavaScript than a POST one.

over 1 year ago ·

What about benchmark to compare performance?

over 1 year ago ·

Did a experimental and minimal test to this. Ordinary wp-ajax gave me a response time at 250ms. This approach gave me 100ms.

over 1 year ago ·

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

over 1 year ago ·

Converted this code to a WordPress plugin...
https://github.com/EkAndreas/ajaxflow
and wordpress.org repo plugin http://wordpress.org/plugins/ajaxflow/

over 1 year ago ·

This can't possibly ever work, do_action won't do anything.

over 1 year ago ·

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.

over 1 year ago ·

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.

over 1 year ago ·

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

over 1 year ago ·

update: it works fine on http but not on https

over 1 year ago ·

Action hook not fired

over 1 year ago ·