-1

I am working a WordPress plugin containing a shortcode. This shortcode, is slow (4 sec to execute), due to external API calls, and I need them here, because they will vary on the user id, watching the page.

Actually, I am in the development/testing stage of my plugin. I am trying to implement a fallback behavior which will skip the long API calls, if a certain time is reached, then using a local logic.

I would like to know, if stopping the execution or conditionally render a shortcode is possible? Using a While loop is not a solution as it will loop at least once.

Additionally, I tried using set_time_limit(); PHP in-built function, but it does not seems to work inside WP environment.

Furthermore, I am trying to achieve this without AJAX, if possible. If not i would like also some guidelines, if you can help me, of course.

If you think I need another solution, for example not using shortcode, please advise me. Lazy loading is could also be a solution as in this thread:

What I am trying to achieve would be to have a asynchronous shortcode, possibly with a loader, looking like the modern JS Web Application.

To monitor the execution time of my shortcode, I have inserted this into my function:

<?php
function my_function() {
  $start = microtime(true);
  // function code here
  $time_taken = microtime(true) - $start;
  wp_die( $time_taken ); // in seconds
}

From this source Thank you, any clues will be useful to me.

UPDATE

Using the clues given by the comments, Ajax was the way to go. Using the wordpress register_script and localize_script I made it work.

Since I call an Api, the data will change most of the time, but I found out that my js file, holding the behavior is being cached and the values are not updated without an Hard Refresh.

How to prevent, the browser, or Wordpress from caching this?

Thanks

Justin
  • 67
  • 1
  • 5
  • 1
    Something blocking page load even for four seconds, is a bad thing. You _should_ be using AJAX here. Use the shortcode to output some placeholder content or a "loading data ..." message - and then have it automatically trigger an AJAX request to an extra endpoint, that makes the API request, returns the data to the frontend, and inserts it in the position where the shortcode has rendered. https://codex.wordpress.org/AJAX_in_Plugins has a good explanation how to set up AJAX endpoints. – CBroe Jan 26 '22 at 10:19
  • Also, if the API data is not "volatile" in that it changes on every request, resp. is not dependent on user-specific parameters - think about implementing some caching here, so that you don't have to make that API request on every page load to begin with. WP already has a mechanism called Transients to make that kind of stuff easier, https://developer.wordpress.org/apis/handbook/transients/ – CBroe Jan 26 '22 at 10:21

2 Answers2

0

If time is your most important factor, I would create a time constrained loop:

$endafter=time()+4;
$completed=false;

while(time()!=$endafter){
    echo ".";
    //Do something
    $completed=true; //Only gets reached if code before it completes successfully
    break; //will break off the while loop so your API call only runs once
}
if($completed){
    //use the API call data
}else{
    //use some other data
}

As for avoiding unnecessary API calls, you could consider caching them and only doing the API call if new data is needed, say after a certain period of time, or if a value changes. I am uncertain the best way to implement this with the WordPress database object, but I've done it with customizations using straight PHP to compare the timestamp, and if it's expired, update it from the API and update the old timestamp with the current one.

Let me know if that works!

JimmyP624
  • 3
  • 1
  • 1
    Thank you for your response, unfortunately your solution will execute at least once. Which mean that the page loading time will remain the same. I want to, if my api call is too long to execute (more than 1 second) stop everything and do something else which I know will be faster. – Justin Jan 27 '22 at 05:25
0

Using Ajax is the best way to achieve my problem, like in this post: https://stackoverflow.com/a/13614297/18036486

Furthermore, to prevent the javascript which trigger the ajax handler to be cached, a random version number must be added to it via wp_register_script() https://developer.wordpress.org/reference/functions/wp_register_script/ , using for example the time().

<?php
wp_register_script(
    'myscript',
    MAIN_PLUGIN_DIR .'/scripts.js',
    false,
    time(), //random version number
    true);
wp_enqueue_script('myscript');
?>
Justin
  • 67
  • 1
  • 5