Page generation time - ASP.Net MVC

前端 未结 3 461
遥遥无期
遥遥无期 2020-12-12 17:30

I\'m looking for a way to track how long it took for a page to be generated by the server. I know I can use Trace to track this but I need a way to display this per page.

相关标签:
3条回答
  • 2020-12-12 18:03

    It will depend on where you want to include this information. For example you could write an http handler that will display the render time after the </html> tag:

    public class RenderTimeModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.BeginRequest += (sender, e) =>
            {
                var watch = new Stopwatch();
                var app = (HttpApplication)sender;
                app.Context.Items["Stopwatch"] = watch;
                watch.Start();
            };
    
            context.EndRequest += (sender, e) =>
            {
                var app = (HttpApplication)sender;
                var watch = (Stopwatch)app.Context.Items["Stopwatch"];
                watch.Stop();
                var ts = watch.Elapsed;
                string elapsedTime = String.Format("{0} ms", ts.TotalMilliseconds);
                app.Context.Response.Write(elapsedTime);
            };
        }
    
        public void Dispose()
        {
        }
    }
    

    If you want to display render time somewhere in the middle of the html page then this render time will not account for the total page render time.

    0 讨论(0)
  • 2020-12-12 18:21

    You can implement it like a ActionFilterAttribute

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class LoggingAttribute : ActionFilterAttribute
    {
        private readonly Stopwatch _sw;
    
        public LoggingAttribute()
        {
            _sw = new Stopwatch();
        }
    
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            _sw.Start();
            Debug.WriteLine("Beginning executing: " + GetControllerAndActionName(filterContext.ActionDescriptor));
        }
    
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            _sw.Stop();
            var ms = _sw.ElapsedMilliseconds;
    
            Debug.WriteLine("Finishing executing: " + GetControllerAndActionName(filterContext.ActionDescriptor));
            Debug.WriteLine("Time elapsed: "+ TimeSpan.FromMilliseconds(ms).TotalSeconds);
        }
    
        private string GetControllerAndActionName(ActionDescriptor actionDescriptor)
        {
            return actionDescriptor.ControllerDescriptor.ControllerName + " - " + actionDescriptor.ActionName;
        }
    }
    

    Decorate every controller or action-method with it and voila, it spit outs the text in debug.

    EDIT: If you want to print it on the page you could add this snippet to the OnActionExecuted method

    if(filterContext.Result is ViewResult) { //Make sure the request is a ViewResult, ie. a page
      ((ViewResult) filterContext.Result).ViewData["ExecutionTime"] = ms; //Set the viewdata dictionary
    }
    

    Now you have the executiontime saved in ViewData and can access it in the page.. I usually put it in the masterpage like this

    <!-- The page took <%= ViewData["ExecutionTime"] %> ms to execute -->
    
    0 讨论(0)
  • 2020-12-12 18:27

    Yep the Derin Suggestion is the standard Way to do it in an ASP.NEt application, i would just suggest add an if so it does not interfere with non-HTML responses: EDIT: added complete implementation

    public class PerformanceMonitorModule : IHttpModule
    {
    
        public void Init(HttpApplication context)
        {
            context.PreRequestHandlerExecute += delegate(object sender, EventArgs e)
            {
                //Set Page Timer Star
                HttpContext requestContext = ((HttpApplication)sender).Context;
                Stopwatch timer = new Stopwatch();
                requestContext.Items["Timer"] = timer;
                timer.Start();
                 };
            context.PostRequestHandlerExecute += delegate(object sender, EventArgs e)
            {
    
                HttpContext httpContext = ((HttpApplication)sender).Context;
                HttpResponse response = httpContext.Response;
                Stopwatch timer = (Stopwatch)httpContext.Items["Timer"];
                timer.Stop();
    
                // Don't interfere with non-HTML responses
                if (response.ContentType == "text/html")
                {
                    double seconds = (double)timer.ElapsedTicks / Stopwatch.Frequency;
                    string result_time = string.Format("{0:F4} sec ", seconds);
                    RenderQueriesToResponse(response,result_time);
                }
            };
        }
        void RenderQueriesToResponse(HttpResponse response, string result_time)
        {
            response.Write("<div style=\"margin: 5px; background-color: #FFFF00\"");
            response.Write(string.Format("<b>Page Generated in "+ result_time));
            response.Write("</div>");
        }
        public void Dispose() { /* Not needed */ }
    }
    

    you can also add some style to it...

    And remember to register your Module in WebConfig inside httpModules Section:

      <add name="Name" type="namespace, dll"/>
    

    For a Complete Reference about this check the Pro ASP.NET MVC Framework by Steven Sanderson - Chapter 15 - Performance, Monitoring Page Generation Times.

    EDIT:(comment @Pino) Here is the example for my project: alt text http://www.diarioplus.com/files/pictures/example_performance.JPG

    0 讨论(0)
提交回复
热议问题