web-dev-qa-db-ja.com

wordpressでadmin-ajax.phpを高速化する方法

私はフロントエンドのajax経由で呼び出すfunctions.phpのコードを持っています。多くのプラグインがあり、すべてのwpコアとプラグインデータをロードする必要があるため、ロードに約2〜2.5秒かかるadmin-ajaxを使用しています、私は以下のスニペットを実行するためにのみ必要なものをロードするカスタムAjaxハンドラを書く方法を疑問に思っていました、私のコードの簡単なことは、メタデータを取得してジオコマースカスタムフィールドを取得し、ジオロケーション目的でHTTPヘッダーを読み取り、いくつかを実装することですリンク付きのボタンを作成するために定義した変数。

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(); 

} 
1
Islam Mohamed

あなたが探している答えは次のとおりです。

Ajaxは10倍の時間を必要とする/すべきでした

残念ながら、そこにある解決策には、ロードするパーツ/ロードしないパーツ、およびなぜ壊れるのかという非常に詳細な知識が含まれます。 githubの問題/コメントを読んで、これはHTTPSでは機能しないようです。

それ以外の場合は、本当に高速化できません。これについて詳しく調査しました。

しかし、REST AP​​Iを提案できますか? RAは、公開されているデータを取得するだけで素晴らしいです。製品、投稿、その他の情報にすぎない情報を考えてください。

これにより、切り替えを決定したときにスクリプトが大幅に高速化されました。

試してみて、ユースケースに合うかどうかを確認してください。それの外観から、それはします。あなたは何も開示していないので、読み取り専用機能を備えた残りのエンドポイントはあなたに合っています。

ここに私のREST APIとAJAXの1:1テストを示します。

表示に使用するデータを取得するだけです-

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
        },
    });
}

バックエンドに実装:

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 ) );
}

残り:

function get_block_help_data(block_identifier) {

    return jQuery.ajax({
        url: block_help_data.rest_link + block_identifier,
        type: 'GET',
        dataType: 'JSON'
    });
}

バックエンドに実装:

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' ) );
    }
}

20〜30回以上の実行(十分ではありませんが、WP AJAXが少し遅いことをはっきりと確認できます):

RESTの呼び出しにかかった時間:215の高さで最大150ミリ秒。

API呼び出しは常に例外なく、少なくとも〜400-500msかかりました。

これが1つ高いことを無視すると、これは信じられないほどのメリットですが、サンプルが小さいことに留意してください。それは実際にはあまりにも良いと思われるため、テストと更新を続けます。

2
coolpasta