LA.NET [EN]

Feb 20

Today I was called to investigate a performance problem with a page of a web application. It was a simple page, with several tabs where each tab loaded several items from the database. According to the guys that wrote the app, things started getting worse with each tab that got added to the page and, since they didn”t have a lot of experience with ASP.NET, they didn”t understand what was going on. They were also little bit intrigued by the fact that the site took almost 2 minutes to load in production (compared to the 20 seconds it took on the development machine).

Here”s what I found when I looked at the page (just a simple example):

<asp:MultiView runat=”server” ID=”mview”>
        <asp:View>
            <uc1:Demo1 ID=”Demo11″ runat=”server” />
        </asp:View>
        <asp:View>
            <uc2:Demo2 ID=”Demo21″ runat=”server” />
        </asp:View>
</asp:MultiView>

And then, each User Control had similar code to this one:

<%@ Control Language=”C#” ClassName=”Demo1″ %>

<script runat=”server”>
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        //assume you have code here that gets something from bd and
        //binds it to a control
    }
</script>
<div>This is user control 1. Assume this is getting data from someplace</div>

By now, you must have noticed the bold on the previous snippets…So, can you see anything wrong here? At first sight, it really looks like there”s nothing wrong with the previous example. However, there really are lots of things wrong with this approach

The MultiView control keeps a list of Views and will only render the active one. To the programmer that is using the control and doesn”t know its internals, it really looks like a cool control: without almost no work at all, you”ve just built an interface which will let you toggle the current view that is shown to the user. And have I said that you can do athis without writing ny code (ok,you do need to write at least one line to change the active view,but how difficult can it be to write a single simple line of code, right?)! Wow! This control is really great! Do you agree with this? I really hope not…

To see why, lets use our old friend reflector to take a look at the MutiView class. Lets see the current implementation of the Views property (responsible for keeping the list of views that is defined on the page):

[WebSysDescription(“MultiView_Views”), PersistenceMode(PersistenceMode.InnerDefaultProperty), Browsable(false)]
public virtual ViewCollection Views
{
    get
    {
        return (ViewCollection) this.Controls;
    }
}

Now, if you”re like me, you should be seeing alarms firing all over the place :) So, when you use this control, all the views (which are just simple controls) are loaded and added to the control collection of the MultiView control. What this means is that all those controls (views) will go through the page life cycle like if they were added directly on the form control. The only difference is that the MultiView control overrides the Render method so that it renders only the active view (by default, all controls maintained on the Controls property are rendered into the page that is sent to the client):

protected internal override void Render(HtmlTextWriter writer)
{
    View activeView = this.GetActiveView();
    if (activeView != null)
    {
        activeView.RenderControl(writer);
    }
}

Btw, if you”re thinking about the minutes vs seconds (when comparing the production site with the development site) the answer was also simple: the database was on a different machine (which meant, that the page had to make several remote calls to get the data it needed for rendering each view, even though only one would be rendered to the client). Fixing this was simple: they changed the code so that the active user control was loaded dynamically by the page.

Moral of the story: well, this example demonstrates one of the problems of the web forms approach: too much abstraction will end up hurting you!

10 comments so far

  1. Asia
    10:46 am - 6-12-2008

    I have the samay problem and I don”t really get the solution to this:
    “…Fixing this was simple: they changed the code so that the active user control was loaded dynamically by the page.” – You meen what? The resign from using MultiView and dit it another way or they fixed the MultiView solution?

    thx

  2. Luis Abreu
    11:15 am - 6-12-2008

    What I”m saying is that instead of using a multiview control, they changed their code so that only one user control exists on the page. To know which control to load, they check a query string parameter and load the control according to that value. So, if you have several components that do complex stuff during its lifetime in each view, then remove the multiview control and just load the controls dynamically during the initial page processing. If you think about it, you”ll just need one control at each time, so using the MultiView control in these scenarios won”t really giv you much…

  3. Waleed Eissa
    2:19 pm - 7-15-2008

    Well, despite the fact that the post was extremely helpful (and thanks a lot for that), I have to say that it really frustrated me. I came across the MultiVIew control quite recently and was going to use it in some project but being a performance aware developer I always read about anything before I use it and so I came across this post. I really like the idea of the MutliView control because it helps keep the markup (which usually contains more than server controls) in the .aspx file instead of the code behind file, sure I can use inline code (script block with runat=server) but I”m not a big fan of this, I prefer to keep the code in a code behind file. Now, I can”t really find an alternative to MutliView (using the panels approach, ie. placing the controls in multiple panels and show/hide the panels as necessary, suffers from the same problem, all the controls will be loaded with every request), is there a way to keep the markup in the .aspx file without sacrificing performance?

  4. luisabreu
    11:27 pm - 7-15-2008

    Well, I”d say no. You”ll have serious problems with the multiview control specially if your views have controls that perform several database calls. in this case, it”s best to have several user controls and only load the current “view” that is shown to the user.

  5. Waleed Eissa
    12:50 pm - 7-17-2008

    Thanks a lot for your prompt reply but actually I”m not sure I get the answer. How can I load the current view only? Could you give more details please? Also, is there a way to keep the markup in the .aspx file without sacrificing performance?

    BTW, I know it”s completely unrelated to the post, so I”m sorry for asking this, but how do you keep spam out of your blog? I don”t see any captcha in here ..

  6. luisabreu
    1:04 pm - 7-17-2008

    Hello again.

    well, you need to break up the views into several user controls. then you”ll be able to load only one view (ie, only one user control that has the html for the view you want to render). do notice that it all depends on your objective. for instance, if your views don”t go to a database to fecth data, then you probably can keep using the multiview control without any problems.

    regarding the spam, I”m using community server which takes care of that for me.

  7. Waleed Eissa
    1:07 pm - 7-17-2008

    Sorry for spamming your blog :) but actually I wanted to say something about the MultiView control. Well, I say it still can be useful depending on how you use it. In my case (as I referred in my previous post) I was looking for a way to keep the markup in the .aspx file, I very often come across having to return some useful message to the user after some action (have a look on my post on asp.net at http://forums.asp.net/p/1287319/2490577.aspx). So, I say in this case I could put the controls needed for this action in a view and add another view for the success message, and instead of showing/hiding panels I just switch the view, seems good to me and it shouldn”t affect performance as the controls will be loaded anyway when getting and posting the page, what do you think?

  8. luisabreu
    1:16 pm - 7-17-2008

    Again, it depends. suppose you have 2 views. view 1 has some code that hits the db (you”ve put the db cod on the load event of the page) and view 2 has a simple message. If you don”t take care, you”ll have a problem: even though you”re showing the view 2 with the message, the db code will still be run. that”s the problem with the multiview control. This might not be a problem, so, as I”ve said, it all depends on your scenario :)

  9. Anonymous
    10:27 pm - 7-29-2008

    I can”t believe Microsoft would release such amateurish controls, oh wait, yeah I can. This is, for a lack of a better word, absolute junk, written so unprofessionally. Why are we paying these people for their products when they do not work right?

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>