0

I would like to understand the order of how Razor engine execute the c# code started with @.

I was trying to see the different times when the Controller is executed and the view is executed. So, I created this very simple ASP.NET MVC application. I store the time in a ViewBag variable in the Controller and show it the View, I also show the current time in the view.

The controller have this:

public ActionResult Index()
{
    ViewBag.ProcessingTime = DateTime.Now;
    return View();
}

The view have this:

Processing time: @ViewBag.ProcessingTime<br />

    @{
        int i = 0;
        do
        {
            i++;
            <text>@i<br /></text>
        }
        while (i < 1000000);
        }

Render time: @DateTime.Now 

The result is something like this:

Processing time: 03/03/2012 04:16:48 p.m.
1
2
3
4
[...]
999998
999999
1000000
Render time: 03/03/2012 04:16:48 p.m.

Why if it's clearly taking time to show me the webpage while it executes the if the ProcessingTime in the Controller and the RenderTime in the view is the same?

Ricardo Polo Jaramillo
  • 12,110
  • 13
  • 58
  • 83
  • @AndrewBarber - It does take time to draw all one million text lines. – Travis J Mar 03 '12 at 21:49
  • 3
    @TravisJ There is no 'drawing' going on whatsoever in this code. – Andrew Barber Mar 03 '12 at 21:51
  • @Andrew I thought because it takes a lot of time to show me the page. Now I understand that the delay is because the browser. Don't showing anything but using a larger number I can see different times. Thanks! – Ricardo Polo Jaramillo Mar 03 '12 at 22:12
  • 1
    @RicardoPolo Gotcha; I couldn't even imagine why you thought that would take a long time, because I was thinking only of the code, which does run very fast, and not of the time it takes to download/display the result in the browser. – Andrew Barber Mar 03 '12 at 22:14
  • @RicardoPolo, I would recommend you reading the [YSlow Best Practices](http://developer.yahoo.com/performance/rules.html) for optimizing your web site. You will realize that most of the time is lost in transit and rendering and not on the server. You could *gain* performance very easily by following some rules instead of wasting valuable time and efforts on the server to win what - 20 milliseconds of rendering? Whereas you are wasting 5 seconds on the client. Lots of people focus on optimizing their server side code without realizing that this is not the issue. Of course this doesn't mean ... – Darin Dimitrov Mar 03 '12 at 22:25
  • ... that you should write crap and non-optimized code on the server. It's just that if you experience some concrete performance problems with your site there are some rules to follow. – Darin Dimitrov Mar 03 '12 at 22:26

1 Answers1

4

Remember that the page is rendered on the server. So even if it visually to you it appears very slowly on the client (because you are sending a huge HTML), the actual rendering happens on the server and probably this happens in less than a second as all you do is to loop over 1 million elements.

Try showing the processor ticks and you should notice a difference (and if you don't there must be something fundamentally wrong):

Processing time: @ViewBag.ProcessingTime.Ticks

... your loops and stuff

Render time: @DateTime.Now.Ticks

So the actual execution is the following:

  1. The client requests /home/index.
  2. The controller action executes, stores the current time in the ViewBag and begins executing the view.
  3. The execution of the view is just looping and dumping 1M elements to the response stream which happens very fast, probably in less than a second. So when it reaches the last line of the view in less than a second or so, this last line is sent to the client.
  4. Lots of time (compared to the execution on the server) takes for this stream to reach the client.
  5. Lots of time (compared to the execution on the server) takes for the client to build a DOM tree and show it.
  6. At last the client shows the state of what was generated on the server which happened pretty fast.
  7. In your browser you observe pretty close times and yet lots of time happened between this page render in this browser.
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • It takes a while to draw all one million text fields. – Travis J Mar 03 '12 at 21:48
  • 2
    @TravisJ, this drawing happens **on the client**. That's why it is slow. The actual code executes **on the server**. There's a huge difference. The time that elapses between the two DateTime measurements on the server is very small. – Darin Dimitrov Mar 03 '12 at 21:50
  • 3
    @TravisJ The server is not 'drawing' anything. It is merely dumping data into a bufferred stream. That happens *very fast* – Andrew Barber Mar 03 '12 at 21:52
  • @DarinDimitrov - I see, so the server is just building the text to be sent to the client even though it is done through the razor syntax. – Travis J Mar 03 '12 at 21:56
  • 2
    @TravisJ I'm confused why you think Razor has anything to do with this. Output is buffered by default. It works the same in WebForms, or if you generate the page with `Response.Write()` calls in the Controller. – Andrew Barber Mar 03 '12 at 21:58
  • @AndrewBarber - Because the second call to date is done through the razor engine. – Travis J Mar 03 '12 at 22:00
  • Again: You could do effectively the same thing with WebForms or by a similar loop and `Response.Write()` calls in the Controller. The latter method would be even (slightly) faster. – Andrew Barber Mar 03 '12 at 22:00
  • 2
    @TravisJ, think of all the route parsing, controller action execution and razor view rendering as a single IHttpHandler.ProcessRequest action that happens on the server and streams the response to the socket. – Darin Dimitrov Mar 03 '12 at 22:01