admin管理员组文章数量:1414604
I have some code on functions.php that I call via ajax on frontend, I'm using admin-ajax which takes about 2 to 2.5 seconds to load since I have many plugins and that ajax handler need to load all wp core and plugins data, I was wondering how to write a custom ajax handler that only load what is required only to run my snippet below, the brief of my code is that it get woocommerce custom fields via get meta data and read HTTP header for geolocation purpose and implement some variables that I defined to create a button with a link.
function simple_amz_link_ajax() {
?>
<script>
jQuery(document).ready(function(){
jQuery.ajax({
url: "<?php echo admin_url('admin-ajax.php?action=get_amz_btn'); ?>",
type: 'POST',
data: {
action: 'get_simple_amz_button',
postId: <?php echo get_post()->ID; ?>
},
dataType: 'html',
success: function(response) {
jQuery("#buy_amz_btn_wrap").html(response);
}
});
});
</script>
<!-- end Ajax call to get_simple_amz_button -->
<div id="buy_amz_btn_wrap">
<div class="spinner">
<div class="bounce1"></div>
<div class="bounce2"></div>
<div class="bounce3"></div>
</div>
</div>
<?php
}
add_action('wp_ajax_get_simple_amz_button', 'simple_amz_button');
add_action('wp_ajax_nopriv_get_simple_amz_button', 'simple_amz_button');
function simple_amz_button() {
// Variables Declaration
$postId = filter_input( INPUT_POST, 'postId', FILTER_SANITIZE_NUMBER_INT );
$de_asin = get_post_meta( $postId, "wccaf_de_asin", true );
$country_code = $_SERVER ["HTTP_CF_IPCOUNTRY"];
$not_avilable_country = '<div id="amz_not_avilable" class="amz_not_avilable">This product is not avilable in your country yet</div>';
// Get Amazon Button Title
if (ICL_LANGUAGE_CODE == "de") {
$amz_btn_title = 'Kaufen auf Amazon';
$not_avilable_country = '<div id="amz_not_avilable" class="amz_not_avilable">Dieses Produkt ist in Ihrem Land noch nicht verfügbar</div>';
}
if (ICL_LANGUAGE_CODE == "en") {
$amz_btn_title = 'Buy on Amazon';
$not_avilable_country = '<div id="amz_not_avilable" class="amz_not_avilable">This product is not avilable in your country yet</div>';
}
//////////////////////////////////////////////
// Geolocation Condition
if ($country_code=="DE" or $country_code=="DE" or $country_code=="AT" or $country_code=="CH" or $country_code=="LI" or $country_code=="EG") {
$associate_id = "bonstato-21";
$access_key = "HDUHWUIDIUWJDWDWDWD";
$secret_key = "HDUIWQDUQWUDJUIQJWDJWQD";
$amazon_domain = "amazon.de";
$asin = $de_asin;
}
/**********************************************************************************/
// Get price from amazon
$amazon = new AmazonAPI($associate_id , $access_key, $secret_key , $amazon_domain);
$item = $amazon->item_lookup($asin)->get_item_data();
if ($item->price != "0" && $item->price != null ) {
?><div class="amz_price_wrap_wrap" >Price: <?php echo $item->price; ?></div><?php
}
global $post;
$product = wc_get_product( $postId );
$type = $product->get_type();
if( $type == 'simple' && $item->price != "0" && $item->price != null ){
if( wp_is_mobile() ) {
// Amazon Link For Mobile
?>
<div class="buy_amz_btn_wrap" >
<button type="button" id="buy_amz_btn" class="buy_amz_btn" onclick="window.location='https://<?php echo $amazon_domain ?>/dp/<?php echo $asin ?>/?tag=<?php echo $associate_id ?>';"><i class="fa fa-amazon fa-amz"></i><?php echo $amz_btn_title ?></button>
</div>
<?php
}
else {
// Amazon Link For PC
?>
<div class="buy_amz_btn_wrap" >
<button type="button" id="buy_amz_btn" class="buy_amz_btn" onclick="window.location='https://<?php echo $amazon_domain ?>/gp/aws/cart/add.html?AssociateTag=<?php echo $associate_id ?>&ASIN.1=<?php echo $asin ?>&Quantity.1=1';"><i class="fa fa-amazon fa-amz"></i><?php echo $amz_btn_title ?></button>
</div>
<?php
}
}
else if( $type == 'simple' && $item->price == "0"){
echo $not_avilable_country;
}
if(is_null($item->price)){
echo $not_avilable_country;
}
die();
}
I have some code on functions.php that I call via ajax on frontend, I'm using admin-ajax which takes about 2 to 2.5 seconds to load since I have many plugins and that ajax handler need to load all wp core and plugins data, I was wondering how to write a custom ajax handler that only load what is required only to run my snippet below, the brief of my code is that it get woocommerce custom fields via get meta data and read HTTP header for geolocation purpose and implement some variables that I defined to create a button with a link.
function simple_amz_link_ajax() {
?>
<script>
jQuery(document).ready(function(){
jQuery.ajax({
url: "<?php echo admin_url('admin-ajax.php?action=get_amz_btn'); ?>",
type: 'POST',
data: {
action: 'get_simple_amz_button',
postId: <?php echo get_post()->ID; ?>
},
dataType: 'html',
success: function(response) {
jQuery("#buy_amz_btn_wrap").html(response);
}
});
});
</script>
<!-- end Ajax call to get_simple_amz_button -->
<div id="buy_amz_btn_wrap">
<div class="spinner">
<div class="bounce1"></div>
<div class="bounce2"></div>
<div class="bounce3"></div>
</div>
</div>
<?php
}
add_action('wp_ajax_get_simple_amz_button', 'simple_amz_button');
add_action('wp_ajax_nopriv_get_simple_amz_button', 'simple_amz_button');
function simple_amz_button() {
// Variables Declaration
$postId = filter_input( INPUT_POST, 'postId', FILTER_SANITIZE_NUMBER_INT );
$de_asin = get_post_meta( $postId, "wccaf_de_asin", true );
$country_code = $_SERVER ["HTTP_CF_IPCOUNTRY"];
$not_avilable_country = '<div id="amz_not_avilable" class="amz_not_avilable">This product is not avilable in your country yet</div>';
// Get Amazon Button Title
if (ICL_LANGUAGE_CODE == "de") {
$amz_btn_title = 'Kaufen auf Amazon';
$not_avilable_country = '<div id="amz_not_avilable" class="amz_not_avilable">Dieses Produkt ist in Ihrem Land noch nicht verfügbar</div>';
}
if (ICL_LANGUAGE_CODE == "en") {
$amz_btn_title = 'Buy on Amazon';
$not_avilable_country = '<div id="amz_not_avilable" class="amz_not_avilable">This product is not avilable in your country yet</div>';
}
//////////////////////////////////////////////
// Geolocation Condition
if ($country_code=="DE" or $country_code=="DE" or $country_code=="AT" or $country_code=="CH" or $country_code=="LI" or $country_code=="EG") {
$associate_id = "bonstato-21";
$access_key = "HDUHWUIDIUWJDWDWDWD";
$secret_key = "HDUIWQDUQWUDJUIQJWDJWQD";
$amazon_domain = "amazon.de";
$asin = $de_asin;
}
/**********************************************************************************/
// Get price from amazon
$amazon = new AmazonAPI($associate_id , $access_key, $secret_key , $amazon_domain);
$item = $amazon->item_lookup($asin)->get_item_data();
if ($item->price != "0" && $item->price != null ) {
?><div class="amz_price_wrap_wrap" >Price: <?php echo $item->price; ?></div><?php
}
global $post;
$product = wc_get_product( $postId );
$type = $product->get_type();
if( $type == 'simple' && $item->price != "0" && $item->price != null ){
if( wp_is_mobile() ) {
// Amazon Link For Mobile
?>
<div class="buy_amz_btn_wrap" >
<button type="button" id="buy_amz_btn" class="buy_amz_btn" onclick="window.location='https://<?php echo $amazon_domain ?>/dp/<?php echo $asin ?>/?tag=<?php echo $associate_id ?>';"><i class="fa fa-amazon fa-amz"></i><?php echo $amz_btn_title ?></button>
</div>
<?php
}
else {
// Amazon Link For PC
?>
<div class="buy_amz_btn_wrap" >
<button type="button" id="buy_amz_btn" class="buy_amz_btn" onclick="window.location='https://<?php echo $amazon_domain ?>/gp/aws/cart/add.html?AssociateTag=<?php echo $associate_id ?>&ASIN.1=<?php echo $asin ?>&Quantity.1=1';"><i class="fa fa-amazon fa-amz"></i><?php echo $amz_btn_title ?></button>
</div>
<?php
}
}
else if( $type == 'simple' && $item->price == "0"){
echo $not_avilable_country;
}
if(is_null($item->price)){
echo $not_avilable_country;
}
die();
}
Share
Improve this question
edited Sep 28, 2018 at 8:29
Abhilesh Sharma
1571 gold badge1 silver badge8 bronze badges
asked Sep 27, 2018 at 23:27
Islam MohamedIslam Mohamed
311 silver badge6 bronze badges
2
- I would note that until all the stuff has been loaded, your code won't run by which time it's too late. You might want to consider not having as many plugins do so many things that it takes 2 seconds? It's difficult to tell without a full copy of your codebase, e.g. you might be doing DB writes, or expensive queries on every request that don't always need to happen, etc – Tom J Nowell ♦ Commented Sep 28, 2018 at 0:59
- Also, have you considered using a REST API endpoint instead of Admin AJAX? – Tom J Nowell ♦ Commented Sep 2, 2019 at 12:25
1 Answer
Reset to default 3Here's the answer you're searching for:
Ajax takes 10x as long as it should/could
Unfortunately, the solution there involves very detailed knowledge of what parts to load / what not to load and why stuff would break. Reading through github issues / comments, it seems this doesn't work with HTTPS.
Otherwise, you really can't speed it up, I've researched this extensively.
But may I suggest the REST API? The RA is amazing for just pulling data that is public. Think products, posts and any other information that's just informational.
This has sped up my scripts by a ton when I decided to switch over.
Give it a try, see if it fits your use case. From the looks of it, it does. You're not disclosing anything, so a rest endpoint with read-only functions would suit you.
Here are my 1:1 tests of Rest API vs. AJAX in my case.
I'm simply retrieving some data that I'll then use to display -
WP AJAX:
function get_block_help_data(block_identifier) {
return jQuery.ajax({
url: block_help_data.ajax_url,
type: 'POST',
data: {
action: 'parse_block_help_request',
security: block_help_data.ajax_nonce,
block_identifier: block_identifier
},
});
}
Implemented in the back-end:
add_action( 'wp_ajax_parse_block_help_request', array( $this, 'parseBlockHelpRequest' ) );
public function parseBlockHelpRequest()
{
check_ajax_referer( 'block_help_nonce', 'security' );
$block_identifier = sanitize_text_field( $_POST['block_identifier'] );
//Check if the data is what we need.
if( ( empty( $block_identifier ) || is_wp_error( $block_identifier ) ) ) {
wp_send_json( 'Invalid data.', 500 );
return;
}
wp_send_json( DataPool::getBlockHelpItem( $block_identifier ) );
}
REST:
function get_block_help_data(block_identifier) {
return jQuery.ajax({
url: block_help_data.rest_link + block_identifier,
type: 'GET',
dataType: 'JSON'
});
}
Implemented in the back-end:
class BlockHelpREST extends \WP_REST_Controller
{
/**
* Holds the namespace for the REST endpoint.
*
* @var string
*/
protected $block_help_namespace = 'block_help/v';
/**
* Holds the version for the REST endpoint.
*
* @var string
*/
protected $block_help_version = '1';
public function __construct()
{
$this->hookRestRouteToServer();
}
/**
* Registers the main routes for the Block Help REST API.
*/
public function registerRoutes() {
$namespace = $this->block_help_namespace . $this->block_help_version;
$base = 'block_identification';
register_rest_route(
$namespace, '/' . $base,
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( new DataPool, 'getBlockHelpItemByREST' ),
//'permission_callback' => array( new Privileges, 'canLoadSprout' )
)
)
);
}
public function hookRestRouteToServer(){
add_action( 'rest_api_init', array( $this, 'registerRoutes' ) );
}
}
Over 20-30 runs (I know, not enough, but I can clearly see with the eye that WP AJAX is a tad bit slower):
The REST call took: MOSTLY 150ms with one high of 215.
The API call always, without exception, took at least ~400-500ms.
Ignoring that one high, this is incredible gains, but do keep in mind, the sample is small. I'll keep testing and update because it, indeed, seems too good to be true.
本文标签: functionsHow to speed up adminajaxphp in wordpress
版权声明:本文标题:functions - How to speed up admin-ajax.php in wordpress 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745193208a2647013.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论