Podczas próby przyspieszenia niektórych wywołań ajaxowych na jednej z naszych stron MVC, natknąłem się na dziwne zachowanie, którego tak naprawdę nie potrafię wyjaśnić. Mam kilka wywołań ajaxowych co N sekund do odpytywania niektórych statystyk.Połączenia Ajax są wolniejsze w stosunku do kontrolera w fizycznie różnym pliku
Wygląda na to, że wywołania ajax do kontrolera w fizycznie innym pliku są znacznie wolniejsze niż podobne wywołania do kontrolera w tym samym pliku fizycznym, z którego pochodzi widok.
Zobacz moje uproszczone przykłady:
Sytuacja 1: Tylko 1 plik
FooController.cs
namespace FooBar.Areas.FooArea.Controllers
{
[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
public class FooTestController: _BaseController
{
public JsonResult GetStats()
{
try
{
var req = new RestRequest() { Method = Method.GET };
req.AddHeader("Content-Type", "application/json");
req.AddHeader("Accept", "application/json");
req.AddParameter("apikey", /*APIKEY*/);
var client = new RestClient(/*STATSURL*/);
var response = client.Execute(req);
if (response.StatusCode == HttpStatusCode.OK)
return Json(new { success = true, content = response.Content });
else
return Json(new { success = false });
}
catch
{
return Json(new { success = false });
}
}
public JsonResult GetAgents()
{
var req = new RestRequest() { Method = Method.GET };
req.AddHeader("Content-Type", "application/json");
req.AddHeader("Accept", "application/json");
req.AddParameter("apikey", /*APIKEY*/);
try
{
var client = new RestClient(/*AGENTSURL*/);
var response = client.Execute(req);
if (response.StatusCode == HttpStatusCode.OK)
return Json(new { success = true, content = response.Content });
else
return Json(new { success = false });
}
catch
{
return Json(new { success = false });
}
}
}
public class FooController : _BaseController
{
// VIEW OF THE PAGE MAKING THE AJAX REQUESTS
public ActionResult Index()
{
Title = "Home";
return View();
}
}
}
Sytuacja 2: 2 oddzielne pliki w tym samym folderze
FooController.cs
namespace FooBar.Areas.FooArea.Controllers
{
public class FooController: _BaseController
{
// VIEW OF THE PAGE MAKING THE AJAX REQUESTS
public ActionResult Index()
{
Title = "Home";
return View();
}
}
}
FooAjaxController.cs
namespace FooBar.Areas.FooArea.Controllers
{
[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
public class FooAjaxController: _BaseController
{
public JsonResult GetStats()
{
try
{
var req = new RestRequest() { Method = Method.GET };
req.AddHeader("Content-Type", "application/json");
req.AddHeader("Accept", "application/json");
req.AddParameter("apikey", /*APIKEY*/);
var client = new RestClient(/*STATSURL*/);
var response = client.Execute(req);
if (response.StatusCode == HttpStatusCode.OK)
return Json(new { success = true, content = response.Content });
else
return Json(new { success = false });
}
catch
{
return Json(new { success = false });
}
}
public JsonResult GetAgents()
{
var req = new RestRequest() { Method = Method.GET };
req.AddHeader("Content-Type", "application/json");
req.AddHeader("Accept", "application/json");
req.AddParameter("apikey", /*APIKEY*/);
try
{
var client = new RestClient(/*AGENTSURL*/);
var response = client.Execute(req);
if (response.StatusCode == HttpStatusCode.OK)
return Json(new { success = true, content = response.Content });
else
return Json(new { success = false });
}
catch
{
return Json(new { success = false });
}
}
}
}
W obu sytuacjach, połączenia są wykonane z Ajax jQuery następująco:
jQuery
$.ajax({
url: // URL TO ACTION DEPENDING ON SITUATION,
type: "POST",
dataType: "json",
cache: false,
success: function (result)
{
if (result.success)
{
var content = JSON.parse(result.content);
console.log(content);
}
}
});
Teraz czasy odpowiedzi z ajax wniosków dotyczących obu sytuacjach są następujące, ze sytuacja 1 wyświetlana po lewej i sytuacji 2 na prawej:
Tak, jak można średni czas połączenia wykonanego na GetStats()
i GetAgents()
w sytuacji 1 to odpowiednio: 52,8 ms i 53,8 ms.
Jednak w sytuacji 2, średni czas połączeń jest 486,8 ms i 529,9 ms.
Moje pytanie brzmi: jak to możliwe, że wywołania ajax wywoływane w działaniach są średnio 10 razy wolniejsze, gdy te akcje znajdują się w kontrolerze w fizycznie odmiennym pliku, niż gdy te akcje znajdują się w kontrolerze, który dzieli ten sam plik fizyczny co plik renderujący widok?
Czy to dlatego, że plik zawierający akcję renderowania widoku jest już załadowany i przechowywany w pamięci, podczas gdy oddzielny plik, jak w sytuacji 2, jest otwierany i zamykany za każdym razem, gdy wywoływana jest akcja? Czy może dzieje się coś bardziej złowrogiego?
Podejrzewam, że "OTHER STUFF" może być potrzebne, aby w pełni odpowiedzieć na to pytanie - albo je zawęzić, dopóki nie będzie można opublikować pełnego przykładu pokazującego to zachowanie. –
@AntP Wystarczająco fair. Dodałem "OTHER STUFF", chociaż nie sądziłem, że to by miało znaczenie, ponieważ działania w obu sytuacjach robią dokładnie to samo (wywołanie adresu URL strony trzeciej w celu uzyskania statystyk/agentów). – ZiNNED
Kontrolery z powiązanymi klasami w różnych plikach są kompilowane do biblioteki DLL, więc proces tak naprawdę nie zna różnicy w żaden sposób ... brzmi jak dzieje się coś innego? –