对控制器的Ajax调用需要很长时间

时间:2019-02-12 12:28:07

标签: javascript ajax asp.net-mvc

我有一个从Javascript文件到MVC5控制器的简单ajax调用。此通话大约需要2秒钟。 javascript和controller中的任务都非常简单。我无法显示完整的代码,但是我对整个调用堆栈进行了性能评估。

如果所有动作在不到10毫秒内完成,此延迟来自何处?您可以在下面的图像中看到TTFB为2.12s,我的控制器显然比2,12s(根据我的性能测试为2ms)更早地完成了此操作。

我是否错过了任何网络问题-毫无疑问,因为这都是在我的开发PC上完成的。我还尝试将完全编译的应用程序部署到独立的IIS服务器(UAT,但仍然...)上进行相同操作,结果是相同的。

我唯一想到的是asp.net在控制器方法完成之后并且实际上将JSON数据返回给浏览器之前做了什么?

JavaScript执行:

1: 1.2000 milliseconds (get values)
2: 2.4000 milliseconds (validation)
3: 2.9000 milliseconds (just before Ajax call)
4: 2172.3 milliseconds (inside Ajax Success)
5: 2174.3 milliseconds (last step in Ajax Success)
6: 0, 0, 1 (see below, these are controller values)

控制器执行:

1: 0 milliseconds (Controller init, constructor completed)
2: 0 milliseconds (Action start)
3: 1 milliseconds (Action end (just before return)

JavaScript代码:

// previous steps omitted, you can see the times for steps 1-3.

$.ajax({
    type: "POST",
    url: $("#appPath").val() + "/MyController/TrivialAction",
    data: req,
    cache: false,
    global: false,
    success: function (response) {
        console.log("4: " + (performance.now() - t0) + " milliseconds.")

        // some code here...

        console.log("5: " + (performance.now() - t0) + " milliseconds.")

        console.log(response.StepsInCtrlr);
    },
    error: function (errorxhr, status, error) {
        BootBoxDiplayHtml(errorxhr.responseText);
    }
});

这是控制器的返回方法(根据Peter B的回答)

return Json(new
    {
        IsError = resp.IsError,
        ErrorMessage = string.Join("<br>", resp.ErrorMessages),
        Amount = resp.Amount.ToString("n2")
    }, JsonRequestBehavior.AllowGet);

(不是上面的确切要求,而是类似的要求)

enter image description here

2 个答案:

答案 0 :(得分:1)

您所说的“动作结束(在返回之前)”确实 完全没有 表示完成MVC:

  • 如果您指定了return View(YourModel);,则MVC会使用Model对象将指定的View呈现为HTML,这会花费时间。

  • 如果您执行了return YourModel;return Json(YourModel);之类的操作,则MVC会将YourModel序列化为JSON。这似乎很简单,但是...吗?如果YourModel恰好是一个 live 实体框架对象,则可能是仅在此阶段实体框架意识到它需要 generate < / em>和 then 触发其数据库查询,以便为您提供数据。而且只有在那之后,序列化才能真正开始。

您需要调查更多在视线之外和在幕后发生的事情。尝试构造与实体框架断开连接的实际ViewModel对象,然后通过Action方法执行return YourViewModel;。如果这样做,则可能会看到处理时间转移到了Action方法内的 代码中,而不是在幕后,然后可以尝试对其进行优化。

答案 1 :(得分:1)

如果您在缺少时间的情况下收到持续的冷热长请求,则可能指向您正在使用的IoC项目。

我已经看到其中一些人花了0.5秒来解决请求,这意味着您会浪费时间在黑洞中。

我在大型应用程序中经历了Ninject吞咽将近0.4s的时间,实在太多了。我将该项目移植到SimpleInjector上,它几乎是瞬时的。

尽管SimpleInjector可以使您遵循更严格的规则集,并且不提供某些依赖项的自动配置,但它确实为您提供了超快的解决时间,为您付出了更多努力。现在,当我放入IoC时,这已成为事实上的标准。