【问题标题】:Ajax request is too slow using Yii2 Framework使用 Yii2 框架的 Ajax 请求太慢
【发布时间】:2018-07-01 15:08:39
【问题描述】:
$(function () {
    $('#barcode-form').on('submit', function (e) {
      $.ajax({
        type: 'post',
        url: '<?= Url::to(['/sales/cart-barcode']) ?>',
        data: $('#barcode-form').serialize(),
        success: function () {
            $( '#barcode-form' ).each(function(){this.reset();});
            document.getElementById("pcode").focus();
        }
      });
    });
});

这是 jQuery AJAX 函数,它运行良好,但它需要大约 2700 毫秒,这是任何客户都不能接受的。

<form  id="barcode-form">
    <?php
    $a=array();
    foreach ($productsAvailable as $product){      
        array_push($a,$product->product_code);
    }

    echo TypeaheadBasic::widget([
        'name' => 'pcode',
         'id' => 'pcode',
        'data' =>  $a,
        'options' => ['placeholder' => 'Filter as you type ...'],
        'pluginOptions' => ['highlight'=>true],
    ]); 
    ?> 
    <input type="submit" hidden/>
</form>

在后端,我正在获取 AJAX 请求的数据并编辑我的表格,如下所示:

public function actionCartBarcode() {
    $request = Yii::$app->request;

    $productCode = $request->getBodyParam('pcode');



    $invoice = Invoice::find()->where(['status' => 1])->one();
    $invoiceId = $invoice->invoice_id;
    $product = AppProduct::find()->where(['product_code' => $productCode])->one();
    $productId = $product->product_id;
    //first see if product exist (change sales to cart after you create the cart table)
    $model = Sales::find()->where(['r_product_id' => $productId])->andWhere(['r_invoice_id' => $invoiceId])->one();
    if ($model) {
        $model->sold_product_qty += 1;
    } else {

        $model = new Sales();
        $model->r_invoice_id = $invoiceId;
        $model->r_product_id = $productId;
        $model->sold_product_qty = 1;
        $model->discount = 0;
        $model->price_per_unit = $product->product_price;
        $model->total_price = $product->product_price;
        $model->profit = $product->product_price - $product->product_cost;
    }
    if ($model->save()) {
        return 1;
    } else {
        VarDumper::dump($productId, 10, true);
        die();
    }
}

有人有想法吗?

【问题讨论】:

  • 您告诉我们您的 ajax 请求很慢 - 但您没有向我们展示由 ajax 发布请求执行的服务器端代码 - 所以很难找到性能问题
  • 我已经编辑了我的代码,看看
  • 您的查询可能会很慢,具体取决于 Sales/Invoice/AppProduct Table 包含多少条目 - 但您需要更深入地调试它(例如,检查 microtime 每个操作需要多长时间) - 其他一些输入 - 获得第一张发票有意义吗? - 它不应该是特定于用户的吗?
  • 是的,在我的情况下,不需要特定于用户,我调试似乎重新加载购物车 div 大约需要 1.5 秒的操作,以在我正在使用的 html 前端显示新内容pjax 重新加载 $.pjax.reload({container: '#cart-pjax', async: false});
  • 如果有任何可能,加入所有或几个查询并构建一个查询(这将减少查询编译和执行时间)。另外,检查每个模型相关行的执行时间;为了了解哪个部分花费更多时间..!例如 - $time_start = microtime(true); $invoice = Invoice::find()-&gt;where(['status' =&gt; 1])-&gt;one(); echo $time_end = microtime(true) - $time_start;

标签: php jquery ajax performance yii2


【解决方案1】:

你需要做一些profiling 来找到慢的部分代码。在这一点上,你唯一能得到的就是盲目猜测。


但这是我的镜头:

$invoice = Invoice::find()->where(['status' => 1])->one();

你应该非常小心这一点。 one() 没有在查询中隐式设置任何限制。这意味着如果您有 100 万张 status 等于 1 的发票,这会将它们全部加载到 PHP 中并且只选择第一个而忽略其他所有内容。这可能会产生明显但不明显的开销,因为 DBMS 必须找到所有这些额外的 999999 记录并将其发送到 PHP 进程。当您使用 one() 与 where 中的非唯一字段时,您应该明确设置限制:

$invoice = Invoice::find()->where(['status' => 1])->limit(1)->one();

【讨论】:

  • 在我的情况下,我总是只有一张状态=1的发票
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-28
  • 1970-01-01
  • 1970-01-01
  • 2011-08-19
  • 2013-08-16
  • 2013-10-05
相关资源
最近更新 更多