Copied to clipboard

Flag this post as spam?

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


  • Berto 105 posts 177 karma points
    Apr 30, 2012 @ 18:42
    Berto
    0

    Performance "problem" with uQuery

    Hi!

    I'm using only uQuery on my projects, and today, when we deployed a project to a virtual server. We noticed that on calling any page on the site, the processor when to 100% (just one request), and started to debug the issue. After some googling on the subject, some people on umbraco said that the problem might be the Request Url actions per macro that could cause the massive processing (I read that it's beacause some regular expressions). So, I started some experiments and saw that for this macro:

    @using uComponents.Core;
    @using uComponents.Core.uQueryExtensions
    @using System.Linq
    @using umbraco.NodeFactory
    @{
        var footer = uQuery.GetRootNode().GetDescendantNodes().SingleOrDefault(p => p.NodeTypeAlias == "Footer");
        var textos = footer.GetChildNodes().Where(p => p.GetPropertyAsBoolean("hasContent"));
    }
    <div class="instit">
        <ul>
            @foreach (Node item in textos)
            {
                <li><a href="@Html.Raw(item.NiceUrl)">@item.GetPropertyAsString("menuTitle")</a></li>    
            }
        </ul>
    </div>
    

    And got 10 Resolve Urls on the trace, when there are only 5 nodes. This multiplied by n Macros on a page, it can be a problem. For what I've seen, everytime that I get an property on a node (ex: item.GetPropertyAsString("menuTitle") ) it makes an "Resolve Url". I don't if this is a problem with uQuery or with NodeFactory, but like I'm using uQuery, I post it here

  • Lee Kelleher 4020 posts 15802 karma points MVP 13x admin c-trib
    Apr 30, 2012 @ 18:58
    Lee Kelleher
    2

    Hi Berto,

    Thanks for reporting this and investigating further.

    From looking at your code snippet, I'd say the problem isn't with uQuery specifically - there are a couple of things that can be done to improve performance here.

     

    * The "Resolve URLs" is enabled in Umbraco by default, which is used to resolve URL paths for virtual directories.  There are known performance issues with this and since Umbraco 4.7.2 it has been switched to disabled by default.  To disable it manually, open your "/config/umbracoSettings.confg" and change the value for "ResolveUrlsFromTextString" from "true" to "false".

     

    * The uQuery for the "footer" and "textos" variables, could be much leaner... instead of getting the root node and navigating downwards, you could try:

    var textos = uQuery.GetNodesByXPath("//Footer[@isDoc][1]/*[@isDoc and string(hasContent) = '1']");

    (Obviously, I've just written that off the top of my head - completely untested, but it *should* work)

     

    Cheers, Lee.

  • Berto 105 posts 177 karma points
    Apr 30, 2012 @ 19:31
    Berto
    1

    Hi Lee,

    Thank you so mutch for that tip! It worked!!!!! I thought that the problem wasn't about uQuery, but just in case, I posted here. The macro that I posted was done in a rush, so it's the most performant one ;) 

    I didn't know that method, and my xslt skill's wen't dead with the appearence of razor :D, but from now on I'll will try to use that method more often.

    Once again, thx, you just saved my day!

    Berto

  • Lee Kelleher 4020 posts 15802 karma points MVP 13x admin c-trib
    Apr 30, 2012 @ 19:35
    Lee Kelleher
    0

    Hi Berto, I'm happy to help.

    The performance of the XPath method is only better as Umbraco's node data is stored as XML (in v4); for v5 you'd query using LINQ expressions.

    Think the bigger issue was the internal "Resolve URLs" call. But glad that you've got it sorted now.

    Cheers, Lee.

  • Berto 105 posts 177 karma points
    Apr 30, 2012 @ 19:45
    Berto
    0

    Hi Lee, 

    I work with umbraco since version 4.0.2 (i think, a little more then 3 years) so i know that xslt and xml schema (both old an new), but i like linq so mutch... 

    For now we are still with v4 because of development time (it's crush time), but I really, really hope to deploy my first v5 project soon :D

    Cheers!

  • Hendy Racher 863 posts 3849 karma points MVP 2x admin c-trib
    Apr 30, 2012 @ 20:18
    Hendy Racher
    1

    Hi Berto, just a thought, but how about a blend of XPath and Linq as a balance on performance / readability ?

    Performance wise this should be fine (unless you have 1000's of child nodes under the footer that don't have content - hence they wouldn't have needed to be constructed in order to perform the hasContent check)

    @using uComponents.Core;
    @using uComponents.Core.uQueryExtensions
    @usingSystem.Linq
    @using umbraco.NodeFactory
    @{
    var textos = uQuery.GetNodesByType("Footer") // uses XPath internally so fast to get this Node
    .Single() // have assumed it should only find one Footer Node
    .GetChildNodes() // this method is slower than pure XPath as has to construct each child Node
    .Where(p => p.GetProperty<bool>("hasContent");
    }
    <div class="instit">
       
    <ul>
           
    @foreach(Node item in textos)
           
    {
           
    <li><ahref="@Html.Raw(item.NiceUrl)">@item.GetProperty<string>("menuTitle")a>li>    
           
    }
       
    </ul>
    >
  • Berto 105 posts 177 karma points
    May 01, 2012 @ 16:48
    Berto
    0

    Hi Hendy, nice ideia!

    I'm already using your sugestion on antoher project, with good results.

    Thx!

    Berto

Please Sign in or register to post replies

Write your reply to:

Draft