代码之家  ›  专栏  ›  技术社区  ›  Iztoksson

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

  •  0
  • Iztoksson  · 技术社区  · 5 年前

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

    如果所有操作在10毫秒内完成,那么这个延迟是从哪里来的?您可以在下面的图像中看到,TTFB为2.12s,我的控制器在2.12s(根据我的性能测试,2ms)之前完成此操作。

    我是否错过了类似网络问题的任何事情——怀疑这一切都是在我的dev pc上完成的。我还尝试过将完全编译的应用程序部署到独立的IIS服务器(UAT,但仍然是…)上,结果是相同的。

    我唯一想到的是ASP.NET在Controller方法完成之后和实际将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 回复  |  直到 5 年前
        1
  •  1
  •   Slicksim    5 年前

    如果你得到持续的冷暖长时间的请求,却没有时间,那么它可能指向你正在使用的IOC项目。

    我见过他们中的一些人用0.5秒来解决一个请求,这意味着你在黑洞里浪费时间。

    我在一个大规模的应用程序中经历了近0.4秒的忍者吞咽,太多了。我把那个项目报告给了SimpleInjector,几乎是瞬间完成的。

    虽然simpleInjector使您保持更严格的规则集,并且不提供一些依赖项的自动配置,但它确实奖励您以闪电般的快速解决时间完成额外的任务。现在,当我加入国际奥委会时,这是我的诽谤标准。

        2
  •  1
  •   Peter B    5 年前

    你所说的“行动结束(就在返回之前)”是 一点也不 意味着MVC完成:

    • 如果您指定 return View(YourModel); 然后,MVC使用模型对象将指定的视图呈现为HTML,这需要时间。

    • 如果你做了类似的事 return YourModel; return Json(YourModel); 然后,MVC将把您的model序列化为json。这可能看起来很简单,但它是…?如果 YourModel 碰巧是 居住 实体框架对象,那么它可能是 只有在这个阶段 实体框架意识到它需要 生成 然后 启动它的数据库查询以向您提供数据。只有在这之后,序列化才能真正开始。

    你需要更多地调查在看不见和幕后发生的事情。尝试构造一个实际的ViewModel对象, 与实体框架断开连接 然后做 return YourViewModel; 从操作方法。如果这样做,您可能会看到处理时间转移到代码上。 里面 操作方法,而不是幕后操作,然后您可以尝试对此进行优化。