Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Hubert 7 posts 27 karma points
    Oct 19, 2011 @ 20:33
    Hubert
    0

    Is Umbraco horribly slow?

    Hi

    I am new here so hello to everybody :)

    I have installed Umbraco 4.7.0 using MS WPI on my local machine. I have used MS SQL CE as database which seemed to be nice option for as small website as mine. Then I have defined document types, created templates etc. My whole site has about 36 nodes which are shown on 10 pages, so it's ultra simple. When i run it on my local web server (Web Matrix+IIS Express) site works well (and fast). The problem is, when I publish it to the hosting server, everything slows down horribly.

    Rendering homepage takes about 1 second, and whole homepage takes about 3.5 seconds to load. I have saved rendered HTML page and uploaded to the server to see speed difference. Static HTML is twice as fast as Umbraco generated homepage. Here you can find the comparison:

    http://gtmetrix.com/compare/JffXU5Es/MTfyCYfc

    The real problem is with subpages which are built with several nodes. For example "O nas" ("About us") page (http://simplymind.pl/o-nas.aspx)  is built on 6 nodes and takes ages to fully load. Server needs about 1.7s to start sending html to the browser.

    There is no error in server logs, instance logs, elmah logs and ay other logs ;)

    So, the question is - what to do to speed up that site?

  • Dan Diplo 1554 posts 6205 karma points MVP 6x c-trib
    Oct 19, 2011 @ 22:05
    Dan Diplo
    0

    If your site is fast on your own server but not on your host then that points to a problem with the host server. I've done lots of Umbraco sites and found it always to be very fast - it's used by some really big sites now.

    Static HTML will always be faster than dynamic content - that is perfectly natural. And it's not true to say, "Static HTML is twice as fast as Umbraco generated homepage" as the speed test you link to show 3.21s for Umbraco and 2.34s for static, which shows that static HTML is about 50% slower, not a 100%. In fact, your page loaded much faster than that for me - it was amost instantaneous.

    You could try enabling debugging and then add ?umbdebugshowtrace=true to your page URLs to see a trace. This might help you pinpoint the problem. Also make sure you have permissions correct on server so that the umbraco.config XML file can be written (in App_Data). If this file is not cached Umbraco will be slow.

    One easy way of improving performance is to add caching to your macros  If that doesn't work then there is something wrong with your host server.

  • Anthony pj 40 posts 63 karma points
    Oct 19, 2011 @ 22:17
    Anthony pj
    0

    Lol i thought this post would not go unchallenged , site also loaded almost instancely for myslef when i naviagted to it...

  • Hubert 7 posts 27 karma points
    Oct 20, 2011 @ 12:20
    Hubert
    0

    Hi

    Thanks for your answers, and info about loading time.

    Different tests show different time, but the linked one seems to be most reliable. My problem is not in loading the whole page, but in waiting for the HTML document to be returned from the server. That's why I wrote that static HTML is twice as fast as Umbraco generated. Rest of the page (images, fonts etc.) is static, so it is served in comparable time. I have made another interesting comparison with some Drupal (PHP) site, which has waiting time similar to waiting for plain HTML document (less than 0,5 second).

    I have tried to use debugging feature of Umbraco, but it does not work in hosting environment. However I have run it on my local server and it did not shown any problems. I can try to cut and paste it here if you want.

    I don't know how to check if the app_data/umbraco.config file is writable, but it seems to be ok, since it has modified date different than other files, and contains all the new strings enetered by the users.

    And the last thing, which may be what I was missing from the start. I am not using macros. I have just put some scripts into the pages, which generates menu or loads children blocks, but those scripts are "inlined". Should I move them to the macros and allow to cache?

  • Dan Diplo 1554 posts 6205 karma points MVP 6x c-trib
    Oct 20, 2011 @ 13:05
    Dan Diplo
    0

    Hi Hubert,

    I would definitely look into using Macros - this is the standard way of doing things in Umbraco and gives you more flexibility. It will also allow you to cache content, as I mentioned, which should give a major performance boost.

    However, I still get a feeling that the problem may be to do with your host, since normally Umbraco is really fast for such small sites.

    I mentioned about umbraco.config being writable since this contains the XML for the entire content of your site. Whenever you publish a page, Umbraco should update this XML. Then, when you write code (either XSLT or Razor) it works against this XML. So long as the XML is there, and updated, Umbraco should be fast.

    Are you using XLST or Razor (or something else) to generate your code? Maybe post an example, as that also may be where the problem is.

  • Hubert 7 posts 27 karma points
    Oct 20, 2011 @ 13:45
    Hubert
    0

    Hi Dan,

    Thanks again for fast answer.

    I have been tought about slow hosting server, but uploaded some other ASP.NET MVC3 application to the same host and run. It runs amazingly fast. So, it's not the host's fault in my oppinion. Another thing I consider is stop using SQL CE. I've chosen it, because of deployment easiness, but I know it is not a speed demon. However, this site is very small, so it should fly anyway ;)

    I have just started looking into macros, and it seems to be correct path. Since it's my first Umbraco installation, I am sure, my macros are not even near to optimal.

    Honestly, I am not even sure if it is Razor or xslt, but i think it's Razor.

    following is my top navigation macro:

    <umbraco:Macro  runat="server" language="cshtml">
    @inherits umbraco.MacroEngines.DynamicNodeContext

    @{ var numberOfItems = 10;
       var currentRoot="";
       string classname="";
       if(@Model.AncestorsOrSelf().Skip(1).Take(1).FirstOrDefault()!=null){
         currentRoot=Model.AncestorsOrSelf().Skip(1).Take(1).First().Name;
       }
    }
    @foreach (var item in @Model.AncestorOrSelf().Children.Where("umbracoNaviHide != true").Take(numberOfItems).OrderBy("UpdateDate")) {
      string [email protected]();
      switch(itemName){
        case "o nas":
        case "co badamy":
          classname="orange"; break;
        case "jak badamy":
          classname="green"; break;
        case "klienci":
        case "kontakt":
          classname="violet"; break;
       }

          if(item.Name==currentRoot){
            <li class="selected @classname"><a href="@item.Url">@item.Name</a></li>
    }else{
            <li class="@classname"><a href="@item.Url">@item.Name</a></li>
    }
        }
    </umbraco:Macro>

    the goal is to assign different classes to different parts of the site (which is realized by assigning the classname) and applying 'selected' class if current node is one of top nodes or one of its children (it has max 2 levels deep).

    Is there a field for optimalization?


  • aghy 129 posts 308 karma points
    Oct 20, 2011 @ 13:48
    aghy
    0

    Hi Hubert,

    To see where umbraco is taking all its time in your web.config near the top in the umbraco keys make sure you have 

    <add key="umbracoDebugMode" value="true" />

    Then go to any of you umbraco pages and add ?umbDebugShowTrace=true (http://simplymind.pl?umbDebugShowTrace=true)

    Hope this helps

    Ben

  • Hubert 7 posts 27 karma points
    Oct 20, 2011 @ 13:57
    Hubert
    0

    Hi Ben

    Thanks for the info, but it still refuses to show trace ;)

    I have following settings:

    <add key="umbracoDebugMode" value="true" />

    and

    <trace enabled="true" requestLimit="10" pageOutput="true" traceMode="SortByTime" localOnly="false" />

    and trace not work in hosting environment.

    Am I missing something?

     

  • aghy 129 posts 308 karma points
    Oct 20, 2011 @ 14:10
    aghy
    0

    Just checked a hosted site I use for testing and it had this:

    <trace enabled="true" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" />

    Which shows localOnly="true" but it still allows me to access ?umbDebugShowTrace=true remotely. I'm not sure if umbraco uses these settings or not.

    I can think why it's not working for you.

    Have you checked all the simple things ... are you editing the correct web.config?

    If you added the umbracoDebugMode key then make sure you dont have another key setting the value to false.

    Ben

  • Dan Diplo 1554 posts 6205 karma points MVP 6x c-trib
    Oct 20, 2011 @ 14:33
    Dan Diplo
    0

    Hubert,

    Your code (which is Razor btw) looks fine - can't immediately see why it is slow. Only optimisation I could see in your code would be changing:

     

    @{ var numberOfItems = 10;
       var currentRoot="";
       string classname="";
       if(@Model.AncestorsOrSelf().Skip(1).Take(1).FirstOrDefault()!=null){
         currentRoot=Model.AncestorsOrSelf().Skip(1).Take(1).First().Name;
       }
    }

    To something like:

    @{ var numberOfItems = 10;
       var currentRoot="";
       string classname="";
       var nodes = Model.AncestorsOrSelf().Skip(1).Take(1);
       if (nodes.FirstOrDefault() != null) {
            currentRoot=nodes.First().Name
       }
    } 

    That way you are only evaluating the nodeset once rather than twice. That might help a little bit, but I doubt you'd notice.

    If you can't see any trace information then maybe your host is overriding trace ouput at the machine.config level - not much you can do about that.

     

  • Hubert 7 posts 27 karma points
    Oct 20, 2011 @ 15:30
    Hubert
    0

    So, I have found that the trace is partially working. Macros are now enclosed in div tags which I was unable to see on the homepage, since there is only part of menu generated by macro, and it is hidden inside ul/li tags. Anyway, there is no diagnostic output about timing on the page. I have tried differen combinations of switches in the

    <traceenabled="true"requestLimit="10"pageOutput="false"traceMode="SortByTime"localOnly="true"/>

    but nothing seemed to change.

    Dan, I've made the change you suggested, and it made the page a bit faster - about 50-100ms. Is there possibility to extract this macro to external file and cache it? Or should I rewrite this macro in XSLT for caching?

    And is the caching a good idea since it has to return different results for different pages?

  • Dan Diplo 1554 posts 6205 karma points MVP 6x c-trib
    Oct 20, 2011 @ 16:02
    Dan Diplo
    0

    Hubert,

    Cacheing macros in Umbraco is easy and works for both XSLT Macros and Razor macros.  You can cache each macro by page, so even if you have different results on each page, each will be cached indvidually. If you go to your Macros section in the Developer section of Umbraco and view a macro you should see three fields at the bottom of the page:

    Cache Period: This is the time in seconds to cache the macro

    Cache by Page:Tick this and a different cache is created per page the macro is on. In your case you should tick this.

    Cache Personalised: Only useful if you have members loging in

    Note that whenever you publish a page in Umbraco the cache is cleared so don't be afraid to use large values.

    For more details please watch:

    http://umbraco.com/help-and-support/video-tutorials/introduction-to-umbraco/developer-introduction/macro-caching.aspx

     

  • Hubert 7 posts 27 karma points
    Oct 20, 2011 @ 18:08
    Hubert
    0

    Dan,

    Thanks for the info about caching. Extracting macros to external files and enabling caching just as you have pointed above made significant speed-up.

    Homepage is fast enough, but I am wondered about the sub-pages which are mure complicated. Let's take "o-nas" ("about-us") page. I has two kind of children nodes - Staff info and AboutUs info. There are three nodes of both kinds. I tought, that it would be faster to split them inside the loop instead iterating the collection twice. So, I re-wrote my macro to the following:

    @inherits umbraco.MacroEngines.DynamicNodeContext

    @{ var numberOfItems = 6;
       var template1="<div class='column onecolumn infobox'><p class='heading'>{0}</p><div class='info'>{1}</div></div>";
       var template2="<div class='column onecolumn staffinfo infobox'><img class='icon' src='{0}' alt='{1}' title='{1}'/><p class='heading'>{1}</p><div class='info'>{2}</div></div>";
       var sb1=new System.Text.StringBuilder();
       var sb2=new System.Text.StringBuilder();  
      }
        @foreach (var item in @Model.Children.Where("umbracoNaviHide != true").Take(numberOfItems).OrderBy("order")) {
          if(item.NodeTypeAlias=="AboutUsItem"){
             sb1.AppendFormat(@template1,@item.name, @item.summary);
             sb1.AppendLine();                                    
          }
          if(item.NodeTypeAlias=="StaffInfo"){
             sb2.AppendFormat(@template2,
                              ((new umbraco.cms.businesslogic.media.Media(@item.photo)).getProperty("umbracoFile").Value),
                              @item.name, @item.summary);  
             sb2.AppendLine();                                
          }
        }
      <div class="row">@Html.Raw(sb1.ToString())</div>

      <div class="row">
        <div class="column threecolumn" style="margin-top:30px;">
          <p class="heading">Zespรณ</p>
        </div>
      </div>

      <div class="row">@Html.Raw(sb2.ToString())</div>

    Generation time for this document, after caching is less then second (compare to 2.1s before caching and optimalization), but honestly, almost 1 second to render page based on 6 nodes does not look good to me. Is there anything else I can tweak?

    I am still thinking about this SQL CE. Is it possible to migrate from CE to regular SQL?

     

     

  • Dan Diplo 1554 posts 6205 karma points MVP 6x c-trib
    Oct 20, 2011 @ 22:30
    Dan Diplo
    0

    The only bit I can see that might cause problems is the creation of Media items (new umbraco.cms.businesslogic.media.Media(@item.photo)) as I believe this hits the database. You could try the alternative "Razor" way of doing this which would be @Library.MediaById(@item.Photo) or new DynamicMedia(@item.Photo) - see http://umbraco.com/follow-us/blog-archive/2011/2/24/umbraco-47-razor-feature-walkthrough-%E2%80%93-part-2

    I think you might be right about SQL CE being the problem, as I've heard of situations where it can be a lot slower than T-SQL. Unfortunately, I don't know any way of swapping database. However, you might be able to create a Package of your site content and re-import it into a new instance using SQL Server.

  • Hubert 7 posts 27 karma points
    Oct 21, 2011 @ 14:32
    Hubert
    0

    Hey

    I have tweak the macro just as you suggested and it seems to be another 50 ms faster :)

    The site works ok right now. I have created some external pinging service to keep application pool alive, and to refresh all of the pages in about 15 minutes interval. I know Umbraco has self-pinging feature, but it stops working when App Pool stops. And the coldstart time takes ages - it is about 10-15 seconds (it's not umbraco fault, it's normal ASP.NET app boot time).

    I think I'll stop for now, I have to read more about creating packages and try to move to SQL Server, but thats for the future.

    And - last but not least - I have to admit, that Umbraco has truly friendliest community on the planet :) 

    Thank you guys - especially Dan - for your help and patience :)

     

  • Mads Krohn 211 posts 504 karma points c-trib
    Nov 24, 2011 @ 23:05
    Mads Krohn
    0

    If your site is running on SQL CE it could explain the problem. If I were you I would definitely try exporting the data to a mssql express server and see if it makes any difference. I believe this tool http://sqlcetoolbox.codeplex.com/ will come in handy :)

Please Sign in or register to post replies

Write your reply to:

Draft