Ian Vink
Ian Vink

Reputation: 68740

What happens after ActionResult returned?

Using MVC 5 I return Json. The total time is 40 milliseconds to get to the point where the data is returned.

However it takes 6000 millisconds for the browser to get the data, even running it on the server.

My question is what happens after I return the value. I am trying to find out what causes the slowness.

    public JsonResult Read(....)
    {
        var all = _userManager.GetStuff();
        var watch = Stopwatch.StartNew();
        var r= Json(all .....);
        Trace.WriteLine("READ" + watch.ElapsedMilliseconds);
        watch.Stop();

        return r;  //Takes 40 milliseconds to get here
    }

Upvotes: 4

Views: 199

Answers (1)

Felipe Oriani
Felipe Oriani

Reputation: 38598

This is the internal code for the JsonResult type.

public override void ExecuteResult(ControllerContext context)
{
  if (context == null)
    throw new ArgumentNullException("context");
  if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
    throw new InvalidOperationException(MvcResources.JsonRequest_GetNotAllowed);
  HttpResponseBase response = context.HttpContext.Response;
  response.ContentType = string.IsNullOrEmpty(this.ContentType) ? "application/json" : this.ContentType;
  if (this.ContentEncoding != null)
    response.ContentEncoding = this.ContentEncoding;
  if (this.Data == null)
    return;
  JavaScriptSerializer scriptSerializer = new JavaScriptSerializer();
  if (this.MaxJsonLength.HasValue)
    scriptSerializer.MaxJsonLength = this.MaxJsonLength.Value;
  if (this.RecursionLimit.HasValue)
    scriptSerializer.RecursionLimit = this.RecursionLimit.Value;
  response.Write(scriptSerializer.Serialize(this.Data));
}

From the point of view the internal code, the JavaScriptSerializer is the type used to serialize the object you pass to the JsonResult. You could check if this is the step where your code is taking slow process.

Try to make your controller like this:

public JsonResult Read(....)
{
    var all = _userManager.GetStuff();
    var watch = Stopwatch.StartNew();

    var scriptSerializer = new JavaScriptSerializer();
    var json = scriptSerializer.Serialize(all);

    Trace.WriteLine("READ" + watch.ElapsedMilliseconds);
    watch.Stop();

    return json;  //Takes 40 milliseconds to get here
}

If the problem persists, you could implement an alternative, you could implement your own JsonResult using the JSON.Net library, which can provide better results. For Sample, add the namespace:

using Newtonsoft.Json; 

The controller:

public JsonResult Read(....)
{
    var all = _userManager.GetStuff();
    var watch = Stopwatch.StartNew();

    var json = JsonConvert.SerializeObject(all);

    Trace.WriteLine("READ" + watch.ElapsedMilliseconds);
    watch.Stop();

    return Content(json, "application/json");  //Takes 40 milliseconds to get here
}

And finally, you could compare the performance. Another possible way is to use another format which can speed up the serialization such as xml or binary.

Upvotes: 1

Related Questions