When trying to speed up some ajax calls on one of our MVC pages, I came across some strange behavior that I cannot explain. I have several ajax calls made every N seconds to poll some statistics.
It seems that the ajax calls made to the controller in a physically different file are significantly slower than the similar calls made to the controller in the same physical file as in the case where the view comes from.
See my simplified examples:
Situation 1: Only 1 file
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", ); var client = new RestClient(); 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", ); try { var client = new RestClient(); 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 {
Situation 2: 2 separate files in one folder
Foocontroller.cs
namespace FooBar.Areas.FooArea.Controllers { public class FooController: _BaseController {
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", ); var client = new RestClient(); 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", ); try { var client = new RestClient(); 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 }); } } } }
In both situations, ajax calls are made from jQuery as follows:
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); } } });
Now the response time from ajax requests for both situations is as follows: on the left, situation 1 is displayed, and situation 2 on the right:

So, as you can see, the average time of a call made in GetStats()
and GetAgents()
in situation 1 is 52.8 ms and 53.8 ms, respectively.
However, in situation 2, the average call time is 486.8 ms and 529.9 ms .
Now my question is: how can it happen that ajax calls made to actions are on average almost 10 times slower when these actions are in the controller in a physically different file than when these actions are in the controller that has the same physical file as The file that displays the view first?
Is it because the file containing the action to render the view is already loaded and stored in memory, while a separate file, as in situation 2, opens and closes each time the action is called? Or is something more sinister going on?