Q: How do I calculate the total time it takes to render an MVC page and display the time on the master page.
In Asp.net Web Form I created a Base page class like so:
public class PageBase : System.Web.UI.Page
{
private DateTime startTime = DateTime.Now;
private TimeSpan renderTime;
public DateTime StartTime
{
set { startTime = value; }
get { return startTime; }
}
public virtual string PageRenderTime
{
get
{
renderTime = DateTime.Now - startTime;
return renderTime.Seconds + "." + renderTime.Milliseconds + " seconds";
}
}
}
I would then call the method on my Master Page like so:
<div id="performance">
<% =PageRenderTime %>
</div>
Q: How do I accomplish the same thing with the MVC Framework?
Q: With the MVC framework where do I set the start time when a page is first created?
The best way to do this is calculate the request timing .. Begin Request and End Request ....
Check out this great post:
http://haacked.com/archive/2008/07/02/httpmodule-for-timing-requests.aspx
Go into your web.config and make sure you have...
<system.web>
<trace enabled="true" localOnly="false" />
</system.web>
Then you can goto http://.../trace.axd and see every request made.
Then you want to look under the From First(s) column and the very last one is the time it took to render the page (server side).
Example...
aspx.page End Render 0.06121112 0.005297
61.2 ms to render the page.
If you're looking to time code itself or you want to manually do some diagnostics you want to use the System.Diagnostics.Stopwatch class not DateTime.
Stopwatch sw = Stopwatch.StartNew();
...
sw.Stop();
Trace.Write(sw.ElapsedMilliseconds);
I would probably override the OnActionExecuting and OnActionExecuted methods on the Controller class.
public class BaseController : Controller {
// Called before the action is executed
public override void OnActionExecuting(ActionExecutingContext ctx) {
base.OnActionExecuting(ctx);
// Start timing
}
// Called after the action is executed
public override void OnActionExecuted(ActionExecutedContext ctx) {
base.OnActionExecuted(ctx);
// Stop timing
}
}
Create a base controller and have your controllers derive from it. Set your start time in the constructor and override Dispose() and put the calculation of the total time there. This should give you an end-to-end on the entire life of the action. Since Controller implements IDisposable, I'm assuming that the render engine will dispose it after the result is computed and you won't have to wait for garbage collection. If my assumption turns out to be wrong, you could use OnResultExecuted() instead.
EDIT: To get the rendering time on the page would be relatively hard because by definition the page can't be done rendering until your time is put on the page and you can't have the time until the page is done rendering. You could, however, write the render time to the session then use AJAX to come back and get the render time for display later. You might be able to approximate it by putting the start time in ViewData and calculating the rendering time in the View itself. You might want to try logging the render time and doing the view approximation and see how close it is.
This code could be used to log the render time.
public class BaseController : Controller
{
private DateTime StartTime { get; set; }
public BaseController() : base()
{
StartTime = DateTime.Now;
}
public override void Dispose( bool disposing )
{
var totalTime = DateTime.Now - this.StartTime;
... write it out somewhere ...
}
}