Copied to clipboard

Flag this post as spam?

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


  • Chuck 71 posts 69 karma points
    Aug 16, 2012 @ 22:06
    Chuck
    0

    Navigation Performance

    Recently we built a new navigation macro using razor and the embeded content picker. The user assosiates the categories they want to appear in the main navigation using the embeded content picker, the razor script then goes and pulls the nodes and node children to build the navigation with dropdowns. 

    The problem that we have run into is that it takes up to 10 seconds to load. We can cache the macro which helps, but we really want to know if there is a better way to increase the performance of this razor script. 

    @{
      
      @*get the Home Node parameterthis is the ID of the node that contains the navigations*@
       var homeNode String.IsNullOrEmpty(Parameter.homeNode@Model.NodeById(1053@Model.NodeById(Parameter.homeNode);
           <ul class="main_nav clearfix">
           @foreach(dynamic navLink in homeNode.mainNavigation{
                                                   
                  var link string.IsNullOrEmpty(@navLink.contentPickerLink.InnerText)  ?  "#"  @Model.NodeById(navLink.contentPickerLink.InnerText).Url;        
                  var linkNodeID string.IsNullOrEmpty(@navLink.contentPickerLink.InnerText)  ?  ""  @Model.NodeById(navLink.contentPickerLink.InnerText);        
                  var maxSubNavLevel string.IsNullOrEmpty(@navLink.maxSubNavLevel.InnerText)  ?   1  int.Parse(@navLink.maxSubNavLevel.InnerText);        
                                                                        
                  <li>
                      <href="@link">@navLink.linkText.InnerText</a>
                                                                 
                       @*if this node has children then run this function again to create sub menu*@
                                                          
                         @if (link != "#"){   
                            if (@linkNodeID.Children.Count(&@linkNodeID.umbracoHideChildren
                              @traverse(@linkNodeID 1@maxSubNavLevel
                            }                                           
                                             
                         }                                                                           
                  </li>                                                                                                                                                                                                                                       
             }
           </ul>
      
      
    }
    @helper traverse(dynamic parentint subNavCountint maxSubNavLevel {
      <ul class="clearfix">
        @*loop through all nodes where umbracoNaviHide is not true*@
        @foreach (var node in parent.Children.Where("Visible"){
          @*create class of "current" if this is the node you are on*@
          var selected Array.IndexOf(Model.Path.Split(',')node.Id.ToString()>= " class=\"current\"" "";
          @*if there is no umbracoRedirectthen use the Url of the node*@
          var navigationURL String.IsNullOrEmpty(@node.umbracoRedirect@node.Url @node.umbracoRedirect;
          @*if there is no specified navTitlethen use the Name of the node*@
          var navigationTitle String.IsNullOrEmpty(@node.navigationTitle@node.Name @node.navigationTitle;
          @*create class of "arrow" for items with sub menu*@
          var subMenuArrow @node.Children.Count(&subNavCount maxSubNavLevel &!@node.umbracoHideChildren " class=\"arrow\"" "";
          var newSubNavCount subNavCount 1;                                                
          <li@Html.Raw(selected)>
            <href="@navigationURL"@Html.Raw(subMenuArrow)>@navigationTitle</a>
            @*if this node has childrenwe have not reached maxLevelsand umbracoHideChildren is not truethen run this function again to create sub menu*@
                                                              
            @if (@node.Children.Count(&subNavCount maxSubNavLevel &!@node.umbracoHideChildren@traverse(node,newSubNavCount,maxSubNavLevel )}
          </li>
          }
      </ul>
    }

  • Tom Maton 387 posts 660 karma points
    Aug 17, 2012 @ 00:11
    Tom Maton
    0

    Hi Chuck,

    One thing that I've found (and seen across forums), not just from Umbraco but Razor/LINQ in general if you change:

    @node.Children.Count() > 0

    to:

    @node.Children.Any()

    This is quicker as my understanding is the .Count() has to iterate through all the items.

    Probably wont solve the whole speed issues, also i recommend installing the mini profiler project http://our.umbraco.org/projects/developer-tools/miniprofiler-for-umbraco will help you narrow the issue more.

    Tom

  • Derrik 29 posts 98 karma points
    Aug 17, 2012 @ 16:04
    Derrik
    0

    Hey Tom,

    I can't seem to get .Any() to work. Is this available in 4.8?

      if(@Model.NodeById(1053).Children.Any(){
        <div>test</div>
      }

    With this code I get the error: Error loading MacroEngine script (file: MainNavigation.cshtml)

Please Sign in or register to post replies

Write your reply to:

Draft