0

I've developed a template page that displays a grid of "employees" (a custom post type). That part works fine, but I also needed to set up a lightbox to display additional details on click. To avoid loading everything at the same time, I've set up an ajax script. This script uses wp-load.php to grab post data based on it's ID.

The template looks like this:

<!-- Hide the lightbox by default -->
<style>
    .lightbox {display:none;}
    .noscroll {overflow:hidden;}
</style>

<!-- This script triggers the lightbox and ajax event -->
<script>
    $(window).bind("load resize scroll", function() {
        $('.employees').each(function(){
            $(this).stop().click(function() {
                var eid = "";
                var eid = $(this).data('id');
                $('body').stop().addClass('noscroll');
                $('.lightbox').stop().fadeIn(250);
                console.log('eid');
                $.ajax({
                    url: '/wp-content/themes/dev/load-employee.php?id='+eid,
                    type:'POST',
                    dataType: 'html',
                    success: function(data){
                        $('.lightbox .html(data).promise().done(function(){
                            $('.lightbox').fadeIn(250);
                        });
                    }
                })
                $('.lightbox').click(function(){
                    $('body').stop().removeClass('noscroll');
                    $('.lightbox .card').stop().fadeOut(250);
                    $(this).stop().fadeOut(250).scrollTop(0);
                });
            });
        });
    });
</script>

<div class="lightbox">
    <!-- Use javascript to append load-employee.php data here -->
</div>

<? $employees = new WP_Query( array( 'post_type' => 'employees', 'posts_per_page' => -1, 'order' => 'ASC' ) );
while ( $employees->have_posts() ) : $employees->the_post();?>
<a class="employee" data-id="<?echo get_the_ID();?>">
    <!-- Echo employee information -->
</a>
<? endwhile; wp_reset_postdata(); ?>

This is the most important part:

url: '/wp-content/themes/dev/load-employee.php?id='+eid,

When the $.ajax script is triggered, it pushes "data-id" to that document through the url. (If there's a better way to do that, please let me know)

load-employee.php looks like this:

<?
// Need this file to make it work
include_once('../../../wp-load.php');

// Get post ID from url
if (isset($_GET['id'])) {
    $id = $_GET["id"];
}else{
    exit;
}

//Use ID to generate single post to echo back to template page.
$args = array('posts_per_page' => 1, 'p' => $id, 'post_type' => 'employees');

$employeepost = get_posts( $args );
foreach ( $employeepost as $post ) : setup_postdata( $post );
?>

<!-- Single post that matches $id is dumped here -->

<? endforeach; ?>

That works too, albeit slow. Once it generates the single post, the data is pushed into the lightbox div.

success: function(data){
    $('.lightbox .html(data).promise().done(function(){
        $('.lightbox').fadeIn(250);
    });
}

So the problem I'm running into is that this whole process is slow. Slow enough that clicking quickly will break things. The most common issue is that the same post will load into the lightbox several times in a row. I'm guessing this is due to the employee-loader.php file taking too much time to process a new request when the ajax script calls for it.

Is there a better way to do this? Perhaps something that doesn't require wp-load.php?

If not, does anyone know how I could optimize what I've got now?

Thanks.

  • 2
    have you seen AJAX in Plugins? – Milo May 5 '16 at 19:47
  • I hadn't, but I'll take a look. Thanks. – mdcrtv May 5 '16 at 21:39
0

You ajax logic seems okay.. In order to solve a duplication problem you need to add a flag.

Example:

var isLoading = false;

-- Your click event is here --

// Only let things to happen if there's no ajax in the middle of process
if( isLoading == false ) {

    // Set it to true - now nothing happens if you click it again
    isLoading = true;

    -- All your ajax logic here --

    // Complete triggers in both cases: "success" or "error"
    complete: function() {

        // Ajax is now done, let's let user to trigger another one if he/she wants
        isLoading = false;
    }
}

Unfortunately ajax in WordPress is not the fastest thing on Earth. WordPress has a lot of junk in the trunk and it needs to load considerable amount of scripts, even with ajax calls.

Try searching online, there might be few tricks and tips to speed up WordPress ajax..

  • Then what is the fastest thing on earth? If you think you can make Ajax fast in WordPress then share your idea on core trac. It is open source everyone ready to accept it, if you've something useful thing other than words! – Sumit May 6 '16 at 5:19
  • @Sumit I've seen few ideas, even in this site, that would disable many WordPress core functions on ajax calls that you wouldn't need. It couldn't be used as core feature because it would be very individual. – N00b May 6 '16 at 5:23
  • And how fast it will be? few ms? People are using stupid paid themes thousand of plugins that makes their site slow. WordPress core with default theme is fastest already even with Ajax. – Sumit May 6 '16 at 5:26
  • @Sumit I built my own very light-weight theme and Im not using plugins but ajax is still multiple times slower than my built custom node.js CMS that has only the stuff that I need. There's no point to argue, WordPress is popular CMS and it needs to fit to all sizes. Some sacrifices has to be made. – N00b May 6 '16 at 5:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.