Copied to clipboard

Flag this post as spam?

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


  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 07, 2012 @ 13:47
    Jeroen Breuer
    0

    Razor menu performance (v4)

    Hello,

    I've created a menu in Razor, but it seems to be pretty heavy and I'm not sure why. Here is the script:

    @inherits umbraco.MacroEngines.DynamicNodeContext
    @using System.Globalization;
    @using umbraco.MacroEngines;
    @using umbraco;
    
    @{
        //Get the top node of the current language.
        dynamic top = Model.AncestorOrSelf(2);
        var currentLanguage = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName.ToLower();
    
        <ul>
    
            @*Render the home button.*@
            @RenderMenu(top, top.menuClass, Model.Id == top.Id && top.hasActiveState, false)
    
            @*Render the other nodes.*@
            @foreach (var c in top.Children.Where("hideInMenu != true"))
            {
                @RenderMenu(c, c.menuClass, Array.IndexOf(Model.Path.Split(','), c.Id.ToString()) >= 0  && c.hasActiveState, true)
            }
    
        </ul>
    }
    
    @*Render the different menu buttons.*@
    @helper RenderMenu(dynamic c, string liClass, bool active, bool renderSubmenu)
    {
        var spanClass = "";
        bool renderChildren = renderSubmenu && c.Children.Where("hideInMenu != true").Count() > 0;
    
        if(renderChildren)
        {
            //Change the css class if a submenu will be rendered.
            liClass = liClass + "_dropdown";
        }
    
        if (active)
        {
            //Add the active class.
            liClass = liClass + " active";
            spanClass = " class=\"active\"";
        }
    
        <li><a href="@c.Url" class="@liClass"><[email protected](spanClass)>@c.menuTitle</span></a>
           @if (renderChildren)
            {
                <ul>
                    @foreach(dynamic d in c.Children.Where("hideInMenu != true"))
                    {
                        <li><a href="@d.Url">@d.menuTitle</a></li>    
                    }
                </ul>
            }
        </li>
    }

    This is the html output:

    <ul>    
    <li><a href="/nl" class="nav_home active"><span class="active">Home</span></a>
    </li>   
    <li><a href="/nl/knapzakken" class="nav_basic"><span>Knapzakken</span></a>
    </li>
    <li><a href="/nl/knaphouders" class="nav_basic"><span>Knaphouders</span></a>
    </li>
    <li><a href="/nl/containers" class="nav_basic"><span>Containers</span></a>
    </li>
    <li><a href="/nl/offerte" class="nav_basic"><span>Offerte</span></a>
    </li>
    <li><a href="/nl/hoe-werkt-knapzak" class="nav_basic_dropdown"><span>Hoe werkt knapzak</span></a>
    <ul>    
            <li><a href="/nl/hoe-werkt-knapzak/meer-gegevens">Meer gegevens</a></li>
            <li><a href="/nl/hoe-werkt-knapzak/nog-meer">Nog meer</a></li>
    </ul>
    </li>
    <li><a href="/nl/contact" class="nav_contact"><span>Contact</span></a>
    </li>
    <li><a href="/nl/login" class="_dropdown"><span></span></a>
    <ul>    
            <li><a href="/nl/login/wachtwoord-vergeten"></a></li>
            <li><a href="/nl/login/registeren"></a></li>
    </ul>
    </li>
    <li><a href="/nl/orderhistorie" class=""><span></span></a>
    </li>
    </ul>

    I assume this shouldn't take too long, but when I look at the trace this is the output: 

    umbracoMacroMacroEngine script added (~/macroscripts/menu.cshtml)0,01399499452847350,000021
    umbracoMacroLoading IMacroEngine script0,01401141937351530,000016
     RazorDynamicNode got datatype a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6 for menuClass on Home0,01552250511736580,001511
     Checking for a RazorDataTypeModel for data type guid a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6...0,0155478267534720,000025
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,01556493596705720,000017
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,01558683576044640,000022
     GUID a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6 does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,0156104464751940,000024
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hasActiveState on Home0,01564466490236460,000034
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,01566895998565560,000024
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,01569393943749010,000025
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,01571447049379240,000021
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,0157346593658230,000020
     RazorDynamicNode got datatype ec15c1e5-9d90-422a-aa52-4f7622c63bea for menuTitle on Home0,01578153861104670,000047
     Checking for a RazorDataTypeModel for data type guid ec15c1e5-9d90-422a-aa52-4f7622c63bea...0,01580172748307730,000020
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,01581815232811910,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,01583834120014970,000020
     GUID ec15c1e5-9d90-422a-aa52-4f7622c63bea does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,01586058317781060,000022
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on ProductOverview0,01804200790993160,002181
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,01806904046739630,000027
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,01808649186525330,000017
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,01810907602718590,000023
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,01813063363630330,000022
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on ProductOverview0,01815561308813780,000025
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,01817443322308160,000019
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,01818983151530830,000015
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,01820967820306720,000020
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,01823226236499980,000023
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on ProductOverview0,01846597422257440,000234
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,01849369114858260,000028
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,01851080036216780,000017
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,0185327001555570,000022
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,01855391558040270,000021
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on ProductOverview0,01857889503223720,000025
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,0185977151671810,000019
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,01861379782795110,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,01863330233143830,000020
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,01865657086191430,000023
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on ProductOverview0,01887214695308860,000216
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,01889781077346650,000026
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,01891423561850830,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,01893476667481070,000021
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,0189552977311130,000021
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on ProductOverview0,01897925063013230,000024
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,01899807076507610,000019
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,01901620653147650,000018
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,01903605321923540,000020
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,01905658427553770,000021
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on Quote0,01925949954865890,000203
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,01928242589486320,000023
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,01929885073990510,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,01931938179620740,000021
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,0193395706682380,000020
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on Quote0,01936352356725730,000024
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,01938268588647280,000019
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,01940116383714490,000018
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,01942066834063210,000020
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,01944085721266270,000020
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on Content0,01969407357372460,000253
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,01971699991992890,000023
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,0197330825806990,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,01975361363700130,000021
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,01977619779893390,000023
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on Content0,01980083506649670,000025
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,01981999738571220,000019
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,01983539567793890,000015
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,01985490018142610,000020
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,01987543123772840,000021
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on Contact0,02008450582774030,000209
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,02010845872675970,000024
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,02012454138752980,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,02014541462810390,000021
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,02016799879003640,000023
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on Contact0,02019263605759920,000025
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,02021179837681470,000019
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,02022753885331310,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,02024704335680030,000020
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,02026757441310260,000021
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on Content0,02046980531768050,000202
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,02049307384815640,000023
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,02050881432465490,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,02052900319668550,000020
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,02055227172716140,000023
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on Content0,02057690899472420,000025
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,0205957291296680,000019
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,02061146960616640,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,02063097410965360,000020
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,02065184735022770,000021
     RazorDynamicNode got datatype a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6 for menuClass on ProductOverview0,1151539042198850,094502
     Checking for a RazorDataTypeModel for data type guid a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6...0,1152000990965650,000046
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,115217208310150,000017
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1152408190248980,000024
     GUID a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6 does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1152664828452760,000026
     RazorDynamicNode got datatype ec15c1e5-9d90-422a-aa52-4f7622c63bea for menuTitle on ProductOverview0,1163193838493130,001053
     Checking for a RazorDataTypeModel for data type guid ec15c1e5-9d90-422a-aa52-4f7622c63bea...0,1163450476696910,000026
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,1163624990675480,000017
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,116383030123850,000021
     GUID ec15c1e5-9d90-422a-aa52-4f7622c63bea does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1164042455486960,000021
     RazorDynamicNode got datatype a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6 for menuClass on ProductOverview0,1164323046589760,000028
     Checking for a RazorDataTypeModel for data type guid a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6...0,1164518091624630,000020
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,1164675496389610,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,116487396326720,000020
     GUID a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6 does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1165099804886530,000023
     RazorDynamicNode got datatype ec15c1e5-9d90-422a-aa52-4f7622c63bea for menuTitle on ProductOverview0,1173592818510250,000849
     Checking for a RazorDataTypeModel for data type guid ec15c1e5-9d90-422a-aa52-4f7622c63bea...0,1173828925657730,000024
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,1173996595950870,000017
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1174201906513890,000021
     GUID ec15c1e5-9d90-422a-aa52-4f7622c63bea does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1174414060762350,000021
     RazorDynamicNode got datatype a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6 for menuClass on ProductOverview0,1174715182921450,000030
     Checking for a RazorDataTypeModel for data type guid a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6...0,1174910227956320,000020
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,117506763272130,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1175269521441610,000020
     GUID a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6 does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1175471410161910,000020
     RazorDynamicNode got datatype ec15c1e5-9d90-422a-aa52-4f7622c63bea for menuTitle on ProductOverview0,1183947314572050,000848
     Checking for a RazorDataTypeModel for data type guid ec15c1e5-9d90-422a-aa52-4f7622c63bea...0,1184179999876810,000023
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,1184351092012670,000017
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1184573511789270,000022
     GUID ec15c1e5-9d90-422a-aa52-4f7622c63bea does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1184789087880450,000022
     RazorDynamicNode got datatype a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6 for menuClass on Quote0,1185066257140530,000028
     Checking for a RazorDataTypeModel for data type guid a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6...0,1185264724018120,000020
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,118542212878310,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1185620595660690,000020
     GUID a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6 does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,118584301543730,000022
     RazorDynamicNode got datatype ec15c1e5-9d90-422a-aa52-4f7622c63bea for menuTitle on Quote0,1194401044072650,000856
     Checking for a RazorDataTypeModel for data type guid ec15c1e5-9d90-422a-aa52-4f7622c63bea...0,1194633729377410,000023
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,1194801399670550,000017
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1195006710233570,000021
     GUID ec15c1e5-9d90-422a-aa52-4f7622c63bea does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1195218864482030,000021
     RazorDynamicNode got datatype a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6 for menuClass on Content0,1195496033742110,000028
     Checking for a RazorDataTypeModel for data type guid a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6...0,1195711609833280,000022
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,1195872436440980,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1196074325161290,000020
     GUID a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6 does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1196286479409750,000021
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on Content0,1213847376233660,001756
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,12140971707520,000025
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,1214268262887860,000017
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1214470151608160,000020
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1214685727699340,000022
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on Content0,1215110036196250,000042
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,1215308503073840,000020
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,1215465907838830,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1215667796559130,000020
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1215869685279440,000020
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on Content0,1217926212752390,000206
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,1218152054371710,000023
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,1218316302822130,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1218542144441460,000023
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1218754298689910,000021
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on Content0,1219014358736410,000026
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,1219205981928560,000019
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,1219363386693550,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1219565275413850,000020
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1219767164134160,000020
     RazorDynamicNode got datatype ec15c1e5-9d90-422a-aa52-4f7622c63bea for menuTitle on Content0,1220290706069870,000052
     Checking for a RazorDataTypeModel for data type guid ec15c1e5-9d90-422a-aa52-4f7622c63bea...0,1220499438475610,000021
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,1220663686926030,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1220862153803620,000020
     GUID ec15c1e5-9d90-422a-aa52-4f7622c63bea does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1221067464366640,000021
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on Content0,1236725816639870,001566
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,1236975611158220,000025
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,1237143281451350,000017
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1237352013857090,000021
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1237564168105550,000021
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on Content0,1237810540781180,000025
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,1238002163973330,000019
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,1238193787165490,000019
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1238392254043080,000020
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1238604408291540,000021
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on Content0,1239100575485510,000050
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,1239316151576680,000022
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,1239476978184380,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1239678866904690,000020
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1239918395894880,000024
     RazorDynamicNode got datatype 38b352c1-e9f8-4fd8-9324-9a2eab06d97a for hideInMenu on Content0,1240157924885080,000024
     Checking for a RazorDataTypeModel for data type guid 38b352c1-e9f8-4fd8-9324-9a2eab06d97a...0,1240346126234520,000019
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,1240506952842220,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1240705419719810,000020
     GUID 38b352c1-e9f8-4fd8-9324-9a2eab06d97a does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1240907308440110,000020
     RazorDynamicNode got datatype ec15c1e5-9d90-422a-aa52-4f7622c63bea for menuTitle on Content0,124140689747680,000050
     Checking for a RazorDataTypeModel for data type guid ec15c1e5-9d90-422a-aa52-4f7622c63bea...0,1241612208039820,000021
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,1241769612804810,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1241974923367830,000021
     GUID ec15c1e5-9d90-422a-aa52-4f7622c63bea does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1242180233930860,000021
     RazorDynamicNode got datatype ec15c1e5-9d90-422a-aa52-4f7622c63bea for menuTitle on Content0,1242536105573430,000036
     Checking for a RazorDataTypeModel for data type guid ec15c1e5-9d90-422a-aa52-4f7622c63bea...0,1242734572451020,000020
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,1242926195643170,000019
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1243124662520760,000020
     GUID ec15c1e5-9d90-422a-aa52-4f7622c63bea does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,124333339492650,000021
     RazorDynamicNode got datatype a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6 for menuClass on Contact0,1243607142343870,000027
     Checking for a RazorDataTypeModel for data type guid a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6...0,1243798765536020,000019
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,1243956170301010,000016
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1244154637178590,000020
     GUID a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6 does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1244387322483350,000023
     RazorDynamicNode got datatype ec15c1e5-9d90-422a-aa52-4f7622c63bea for menuTitle on Contact0,1252972725860440,000859
     Checking for a RazorDataTypeModel for data type guid ec15c1e5-9d90-422a-aa52-4f7622c63bea...0,1253208833007920,000024
     Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...0,1253379925143770,000017
     There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...0,1253588657549510,000021
     GUID ec15c1e5-9d90-422a-aa52-4f7622c63bea does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType0,1253800811797970,000021
    umbracoMacroLoading IMacroEngine script [done]0,4596492884962440,334269
    renderMacroRendering started (macro: , type: 6, cacheRate: 0)0,459720805009030,000072

    It takes almost half a second to just load the menu so something must wrong. Any idea how to increase performance?

    Jeroen

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 07, 2012 @ 13:50
    Jeroen Breuer
    0

    This is how I call the Razor script in my template:

    <div class="global_nav">
    
        <%--Menu--%>
        <umbraco:Macro runat="server" RenderEvent="PreRender" FileLocation="~/macroScripts/Menu.cshtml" />
    
    </div>

    Would it make any difference to make a macro in the backoffice and use that?

    Jeroen

  • Dave Woestenborghs 3504 posts 12135 karma points MVP 9x admin c-trib
    Feb 07, 2012 @ 14:04
    Dave Woestenborghs
    0

    Why do you use Array.IndexOf(Model.Path.Split(','), c.Id.ToString()) >= 0  && c.hasActiveState to check if the menu needs to be active ?

     

    Can't you use c.IsAncestor(Model) ?

  • Anthony Dang 1404 posts 2558 karma points MVP 3x c-trib
    Feb 07, 2012 @ 14:07
    Anthony Dang
    0

    I could be that you're using dynamic. Even though your dynamic objects are of type DynamicNode, they will inherently be slower than instantiating a "real" DynamicNode.

    I normally stay clear of dynamic as much as possible.

    Instantiate your objects eg.

    DynamicNode top = new DynamicNode(Model.Id).AncestorOrSelf(2);

    Then get your values with eg top.GetPropertyValue("menuClass")

    It's a bit more code but visual studio helps with intellisense.

     

     

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 07, 2012 @ 14:08
    Jeroen Breuer
    0

    Some menu items don't need an active state based on the liClass. It's a complicated menu with many options :p. I used Array.IndexOf(Model.Path.Split(','), c.Id.ToString()) >= 0 because that was in one Razor template files when you create a new Razor file in the backend. It was the Navigation example:

    @*
    NAVIGATION BY LEVEL
    =================================
    This snippet makes it easy to do navigation based listsIt'll automatically list all children of a page with a certain 
    level in the hierarchy that'published and visible (it'll filter out any pages with a property named "umbracoNaviHide"
    that'set to 'true'.

    How to Customize for re-use (only applies to Macrosnot if you insert this snippet directly in template):
    If you add Macro Parameter with the alias of "Level" you can use this macro for both level and level navigations
    If you add Macro Parameter with the alias of "ulClass" you can specify different css classes for the <UL/element

    How it works:
    The first two lines (var level..and var ulClassassigns default values if none is specified via Macro Parameters
    Then it finds the correct parent based on the level and assigns it to the 'parent' variable.
    Then it runs through all the visible children in the foreach loop and outputs list item
    Inside the list item it checks if the page added to the list is parent of the current page. Then it marks it 'selected'

    NOTEIt is safe to remove this comment (anything between @)the code that generates the list is only the below!
    *@

    @inherits umbraco.MacroEngines.DynamicNodeContext
    @
      var level String.IsNullOrEmpty(Parameter.Levelint.Parse(Parameter.Level)
      var ulClass String.IsNullOrEmpty(Parameter.UlClass"" String.Format(" class=\"{0}\""Parameter.UlClass)
      var parent @Model.AncestorOrSelf(level);
      if (parent != null{
        <ul@Html.Raw(ulClass)>
        @foreach (var item in parent.Children.Where("Visible"){
          var selected Array.IndexOf(Model.Path.Split(',')item.Id.ToString()>= " class=\"selected\"" "";
          <li@Html.Raw(selected)>
            <href="@item.Url">@item.Name</a>
          </li>
          }
        </ul>
      }
    }

    Jeroen

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 07, 2012 @ 14:10
    Jeroen Breuer
    0

    Hmm if I don't use dynamic I don't need to use DynamicNode at all... Could just use the Node factory in that case and I think DynamicNode is created to be dynamic.

    Jeroen

  • Dave Woestenborghs 3504 posts 12135 karma points MVP 9x admin c-trib
    Feb 07, 2012 @ 14:13
    Dave Woestenborghs
    0

    Jeroen 

    That's not entirely true.

    When you use @Model.Property this will be translated to DynamicNode.GetPropertyValue("Property") under the hood. This translation can lead to a performance hit.

     

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 07, 2012 @ 14:15
    Jeroen Breuer
    0

    I changed this:

    Array.IndexOf(Model.Path.Split(','), c.Id.ToString()) >= 0

    Into this:

    c.IsAncestor(Model)

    But performance is the same.

    Jeroen

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 07, 2012 @ 14:28
    Jeroen Breuer
    0

    Well I tried rewriting it to just use DynamicNode which is not dynamic, but the code get's a lot more and I use things like this a lot which also don't work:

    top.Children.Where("hideInMenu != true")

    So I would really like to keep using dynamic, and I think using that won't make things that much slower. I've used it a lot on other websites and I didn't notice any performance hits.

    Jeroen

  • Dave Woestenborghs 3504 posts 12135 karma points MVP 9x admin c-trib
    Feb 07, 2012 @ 14:31
    Dave Woestenborghs
    0

    In your RenderMenu function you have this twice : c.Children

    Maybe you should store that in a variable

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 07, 2012 @ 14:35
    Jeroen Breuer
    0

    Made it a variable, but no difference. All these things only have a really small impact on performance. I must be missing something else.

    Jeroen

  • Dan Diplo 1554 posts 6205 karma points MVP 6x c-trib
    Feb 07, 2012 @ 14:42
    Dan Diplo
    0

    "Would it make any difference to make a macro in the backoffice and use that?"

    It probably wouldn't solve the underlying problem, but at least you would be able to add caching.

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 07, 2012 @ 14:51
    Jeroen Breuer
    0

    I'll do that once I find the underlying problem :). Want to have this fixed :p. Anyone know a good tool to test performance? Would like to debug my razor file and see what the real bottleneck might be.

    Jeroen

  • Dan Diplo 1554 posts 6205 karma points MVP 6x c-trib
    Feb 07, 2012 @ 15:05
    Dan Diplo
    0

    Out of interest, what database are you using? SQL Server or embedded?

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 07, 2012 @ 15:06
    Jeroen Breuer
    0

    I'm using SQL Server, but does that have anything to do with this Razor file? It only runs against the umbraco.config xml file.

    Jeroen

  • Rodion Novoselov 694 posts 859 karma points
    Feb 07, 2012 @ 15:30
    Rodion Novoselov
    0

    Hi, Jeroen. What is the datatype of the "hideInMenu" property? (I suspect that it's some custom one)

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 07, 2012 @ 15:32
    Jeroen Breuer
    0

    It's a boolean (the true/false datatype). I always use hideInMenu instead of umbracoNaviHide, because we use that for the xml sitemap. Sometimes I want to hide the node in the menu, but still have it in the xml sitemap.

    Jeroen

  • Rodion Novoselov 694 posts 859 karma points
    Feb 07, 2012 @ 15:34
    Rodion Novoselov
    0

    Oh, no. I'm wrong. It's the "menuTitle" property that's of my interest not the "hideInMenu".

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 07, 2012 @ 15:48
    Jeroen Breuer
    0

    That's just a Textstring like other fields. Could use the node name there, but we prefer to keep those separate :).

    Jeroen

  • Rodion Novoselov 694 posts 859 karma points
    Feb 07, 2012 @ 15:50
    Rodion Novoselov
    0

    Hmmm... However it relates to the other properties as well... There's things in the trace that looks a bit suspective for me:

    RazorDynamicNode got datatype a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6 for menuClass on Home
    Checking for a RazorDataTypeModel for data type guid a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6...
    Checking the RazorDataTypeModelTypes static mappings to see if there is a static mapping...
    There isn't a staticMapping defined so checking the RazorDataTypeModelTypes cache...
    GUID a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6 does not have a DataTypeModel, falling back to ConvertPropertyValueByDataType

    As far as I know from the sources it points to the attempt to convert the property value from a string to some "stronger" datatype basing on the datatype ID. I'm just speculating but perhaps the problem is somewhere there.

  • Anthony Dang 1404 posts 2558 karma points MVP 3x c-trib
    Feb 07, 2012 @ 15:59
    Anthony Dang
    0

    Rodion the whole RazorDynamicNode thing is because of the use of dynamic. There will always be a performance hit when using dynamic.

    Jeroen I would just use NodeFactory or DynamicNode. I use extension methods to keep my code concise.

     

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 07, 2012 @ 16:06
    Jeroen Breuer
    0

    @Rodion I think that is a new feature of Umbraco 4.7.1.1. It tries to convert it to a strong type. I already had performance problems with it before (long story, but page load was 120 seconds :p) so perhaps it can be disabled somehow.

    @Anthony I really like to use the DyanmicNode as a dynamic. It makes the code clearer and more flexible. Really a last option to drop dynamic.

    Jeroen

  • Rodion Novoselov 694 posts 859 karma points
    Feb 07, 2012 @ 16:15
    Rodion Novoselov
    0

    I think that dynamics aren't necessary a large performance hit. It depends. In the worst case a dynamic property/method is resolved with the reflection what's definitely not good in performance terms. But on the other hand they can be dispatched through DynamicObject.TryXXX(...) that is the case for DynamicNode and should be much faster that dumb reflection.

  • Anthony Dang 1404 posts 2558 karma points MVP 3x c-trib
    Feb 07, 2012 @ 16:40
    Anthony Dang
    0

    I'm very curious what this performance issue is.

    Jeroen, perhaps you just need to do some old fashion brute force investigation.

    Remove everything until you have no performance issue, then add lines/sections until you see an issue.

     

     

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 07, 2012 @ 16:41
    Jeroen Breuer
    0

    I was thinking about that, but perhaps it's better to do some profiling first? See what the bottle necks are by placing breakpoints and looking at how long each breakpoint takes. Can I already do that with Visual Studio or do I need an extension for that?

    Jeroen

  • Rodion Novoselov 694 posts 859 karma points
    Feb 07, 2012 @ 16:52
    Rodion Novoselov
    0

    I have yet another stupid idea. What if to try to set either RenderEvent="Init" or EnableViewState="false" on that <umbraco:macro> control?

  • Floris Robbemont 57 posts 89 karma points c-trib
    Feb 07, 2012 @ 16:54
    Floris Robbemont
    0

    @Jeroen:

    Are you using a plain website? I would like to fix this as well since my latest project has the same messages in the stack trace.
    I have some time tomorrow, I'll look into it :)

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 07, 2012 @ 17:03
    Jeroen Breuer
    0

    No sure what you mean by plain website, but it's the same as the last website which I sent you a while back :).

    Jeroen

  • Floris Robbemont 57 posts 89 karma points c-trib
    Feb 07, 2012 @ 17:08
    Floris Robbemont
    0

    Same database and code? :)

    Great, I'll test it with that website :)

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 07, 2012 @ 17:15
    Jeroen Breuer
    0

    No different website and database, but the same structure :). I could send it again if you want.

    Jeroen

  • Floris Robbemont 57 posts 89 karma points c-trib
    Feb 07, 2012 @ 18:23
    Floris Robbemont
    0

    If you could send that website to me I can debug it directly using my own build of Umbraco. I'll try to find out what the problem is tomorrow :)

  • Stephen 767 posts 2273 karma points c-trib
    Feb 08, 2012 @ 16:54
    Stephen
    0

    Have you tried to remove the .Where("hideInMenu != true") just to see if that's what causing the perf hit?

    Is it a True/False DataType?

    Do you have an IRazorDataTypeModel defined for the True/False DataType?

     

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 08, 2012 @ 16:57
    Jeroen Breuer
    0

    I tried removing that and it didn't make much difference. I don't have done anything special for the True/False datatype.

    I sent the code to Floris and he's looking at it. Also Gareth might have a look at it.

    Jeroen

  • Anthony Dang 1404 posts 2558 karma points MVP 3x c-trib
    Feb 09, 2012 @ 12:02
    Anthony Dang
    1

    I just had a flashback....I had a similar strange performance issue many months ago.

    After removing all other cshtml files and macros from the page, I found that the issue was to do with AncestorOrSelf, and DescendentsOrSelf when used on Model.

    The fix was : whenever I needed to do AncestorOrSelf I did :

    new DynamicNode(Model.Id).AncestorOrSelf()

    This showed a significant improvement.

    Also, if you need to do AncestorOrSelf(2) in multiple cshtml files on the page to get the root node, you should make a helper method and cache the result in request cache (ie. HttpContext.Items). It drastically reduces the load time.

     

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 09, 2012 @ 12:04
    Jeroen Breuer
    0

    I've already had a talk with Gareth and I know the problem. It's should be related to .Where("hideInMenu != true"). Will post more info soon.

    Jeroen

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 16, 2012 @ 11:07
    Jeroen Breuer
    4

    After some more emailing with Gareth I got it solved :).

    Let me first say this: Dynamic Razor is still good for most situations and it's fast. Only if you want to iterate through a lot of nodes it could cause performance problems.

    Here are parts of the email conversation:

     

    First reaction about performance problem:
    "Well, in short, it's all the property accesses for hideInMenu. The razor datatypes model lookups probably needs some caching love, but that would be an internal fix rather than a fix to your script."

    I asked if this will be fixed:
    "I'm tied up on a project for a few weeks, but I really need to touch base with Niels first. Now u5.0 is out, I know u4 will continue to be used - but I am wondering if my efforts are best spent elsewhere"

    Another reaction about the performance problem:
    "What seems to be calling the slowdown here is the repeated property accesses for hideInMenu that don't seem to be cached (probably a .Where issue, not sure) I was optimising that to use examine but ran into an examine bug in 4.7.0 - I think that's been fixed so in 4.7.2 we will upgrade the examine library (with Niels blessing) It's one of the most used methods so it needs optimisation."

    Solution for the Problem:
    "Yes, load it into a custom object and then use that for your rendering loop - it's less than ideal but seems the best way to solve the performance issue in the interim"

     

    Here is my new code:

    Menu.cshtml

    @inherits umbraco.MacroEngines.DynamicNodeContext
    @using System.Globalization;
    @using umbraco.MacroEngines;
    @using umbraco;
    @using Project.General.BO;
    @using Project.WebApplication.Razor;
    
    @{
        //Get the top node of the current language.
        dynamic top = Helper.GetTop(Model);
    
        //Add the nodes to the menuItems list.
        List<Menu> menuItems = new List<Menu>();
        foreach (var menuItem in top.DescendantsOrSelf(2))
        {
            menuItems.Add(new Menu()
            {
                Id = menuItem.Id,
                ParentId = menuItem.Parent.Id,
                Path = menuItem.Path,
                HideInMenu = (menuItem.GetPropertyValue("hideInMenu") != "0"),
                HasActiveState = (menuItem.GetPropertyValue("hasActiveState") == "1"),
                MenuClass = menuItem.GetPropertyValue("menuClass"),
                MenuTitle = menuItem.GetPropertyValue("menuTitle"),
                Url = menuItem.Url
            });
        }
    
        //Convert the flat list into a nested list and get the first menu item since this is always the top node of the current language.
        Menu nestedMenu = Helper.CreateNestedMenu(menuItems)[0];
    
        <ul>
    
            @*Render the home button.*@
            @RenderMenu(nestedMenu, nestedMenu.MenuClass, Model.Id == nestedMenu.Id && nestedMenu.HasActiveState, false)
    
            @*Render the other nodes.*@
            @foreach (Menu menu in nestedMenu.Children.Where(x => x.HideInMenu == false).ToList())
            {
                @RenderMenu(menu, menu.MenuClass, Array.IndexOf(Model.Path.Split(','), menu.Id.ToString()) >= 0 && menu.HasActiveState, true)
            }
    
        </ul>
    }
    
    @*Render the different menu buttons.*@
    @helper RenderMenu(Menu menu, string liClass, bool active, bool renderSubmenu)
    {
        var spanClass = "";
        List<Menu> children = menu.Children.Where(x => x.HideInMenu == false).ToList();
        bool renderChildren = renderSubmenu && children.Count() > 0;
    
        if (renderChildren)
        {
            //Change the css class if a submenu will be rendered.
            liClass = liClass + "_dropdown";
        }
    
        if (active)
        {
            //Add the active class.
            liClass = liClass + " active";
            spanClass = " class=\"active\"";
        }
    
        <li><a href="@menu.Url" class="@liClass"><[email protected](spanClass)>@menu.MenuTitle</span></a>
           @if (renderChildren)
           {
                <ul>
                    @foreach (Menu childMenu in children)
                    {
                        <li><a href="@childMenu.Url">@childMenu.MenuTitle</a></li>    
                    }
                </ul>
           }
        </li>
    }

    Menu class:

    public class Menu
    {
        public int Id { get; set; }
        public int ParentId { get; set; }
        public string Path { get; set; }
        public bool HideInMenu { get; set; }
        public bool HasActiveState { get; set; }
        public string MenuClass { get; set; }
        public string MenuTitle { get; set; }
        public string Url { get; set; }
    
        public List<Menu> Children = new List<Menu>();
    }

    Static helper method:

    /// <summary>
    /// Convert a flat list of menu items in a nested list.
    /// </summary>
    /// <param name="lines"></param>
    /// <returns></returns>
    public static List<Menu> CreateNestedMenu(List<Menu> menuItems)
    {
        var idLookup = new Dictionary<int, Menu>();
        var roots = new List<Menu>();
    
        foreach (Menu menu in menuItems)
        {
            Menu parent;
            if (idLookup.TryGetValue(menu.ParentId, out parent))
            {
                parent.Children.Add(menu);
            }
            else
            {
                roots.Add(menu);
            }
            idLookup.Add(menu.Id, menu);
        }
    
        return roots;
    }

    After this here are the new performance results:

    Old menu:   0,547868017647013
    New menu:  0,036914941413300

    So using this new code made the website 0,5 sec faster on each pageload which is a huge performance boost! Thanks everyone for helping. #h5yr

    Jeroen

     

  • James Drever 118 posts 149 karma points
    Feb 16, 2012 @ 12:05
    James Drever
    0

    That's really, really useful.  Thanks to Jereon and Gareth for the info.  I found similiar Razor performance issues when iterating lots of nodes - I blogged about it briefly (http://jamesdrever.co.uk/blog/?p=246) - I ended up using Examine to sort the issues.  But in some cases you really don't want to have to do that. Be really good to see a fix at core level - loading into a custom object is really less than ideal.

  • Floris Robbemont 57 posts 89 karma points c-trib
    Feb 16, 2012 @ 13:54
    Floris Robbemont
    1

    I still think this performance issue can be fixed in the core. When I find the time I'll give it try :)

  • Dan Diplo 1554 posts 6205 karma points MVP 6x c-trib
    Feb 16, 2012 @ 14:18
    Dan Diplo
    0

    Can someone clarify something: Is the performance penalty down to the fact that the "where" clause is operating on a custom property("hideInMenu")? Would it be faster if it was operating on a "built-in" Node property, such as "id"? Or is it nothing to do with that?

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 16, 2012 @ 14:25
    Jeroen Breuer
    0

    Not sure, but I think it's because it's a custom property. The "built-in" properties are already strongly typed so they don't need to be casted. At least that's what I think.

    Jeroen

  • Karl Kopp 121 posts 227 karma points
    Feb 28, 2012 @ 22:59
    Karl Kopp
    0

    Has anyone logged a bug on Codeplex for this? Think it should definitely be looked at.

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 29, 2012 @ 06:39
    Jeroen Breuer
    1

    I don't it has been logged on Codeplex yet.

    Jeroen

  • Karl Kopp 121 posts 227 karma points
    Mar 01, 2012 @ 02:45
  • Michael Sims 119 posts 387 karma points
    Nov 21, 2012 @ 22:30
    Michael Sims
    0

    Does anyone know if this has been fixed?

  • Floris Robbemont 57 posts 89 karma points c-trib
    Nov 21, 2012 @ 23:03
    Floris Robbemont
    0

    @Michael:

    Querying Umbraco data from your Razor files (of views if you use the MVC parts of Umbraco) has been completely refactored. It now uses IPublishedContent for statically typed access. You can also use the dynamic way of getting your data.

    You can find all the documentation about this new way of getting data here: http://our.umbraco.org/documentation/reference/mvc/querying/

  • Dmitriy Skudnov 39 posts 64 karma points
    Dec 17, 2012 @ 13:11
    Dmitriy Skudnov
    0

    How is it possible to get such detailed trace for macro rendering with razor?

  • Dan Diplo 1554 posts 6205 karma points MVP 6x c-trib
    Dec 17, 2012 @ 14:09
    Dan Diplo
    0

    @Dimitry - You can append umbDebugShowTrace=true to the URL as a query string parameter. This requires umbracoDebugMode to be set to "true" in the web.config to work.

  • Dmitriy Skudnov 39 posts 64 karma points
    Dec 17, 2012 @ 14:11
    Dmitriy Skudnov
    0

    @Dan Thanks, i know about this function. It is not giving such a detailed trace as Jeroen was posting here. So the question is still in the air

  • Anthony Candaele 1197 posts 2049 karma points
    Feb 07, 2013 @ 15:56
    Anthony Candaele
    0

    Hi Jeroen,

    Thanks for sharing your solution.

    I would like to implement this in my website.

    Just a question. I guess this namespace belong to your particular webproject:

    @usingProject.General.BO;
    @usingProject.WebApplication.Razor;

    Another question I have, is with the static helper method, CreateNestedMenu, did you define this method in a separate class file, or did you define it in the Menu.cs class?

    Thanks for your advice,
    Anthony

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Feb 07, 2013 @ 16:03
    Jeroen Breuer
    1

    Yes those are namespaces from my web project. The static helper is a separate class file. It's not in the Menu.cs class.

    If you're using MVC in 4.10 or higher you don't have this problem anymore.

    Jeroen

  • Anthony Candaele 1197 posts 2049 karma points
    Feb 07, 2013 @ 16:47
    Anthony Candaele
    0

    @Jeroen, oh I see. I'm using Umbraco v4.11.4

    I'm looking for a menu navigation script that list not only top pages, but also subpages. The default Umbraco Razor template for main navigation only seems to list top pages but no subpages.

    greetings,

    Anthony

  • Anthony Candaele 1197 posts 2049 karma points
    Feb 12, 2013 @ 10:35
    Anthony Candaele
    0

    @Jeroen, I implemented your Navigation solution: Navigation.cshtml, Menu.cs and Helper.cs, but apparently the script is complaining about a Helper.getTop() method that is not available in the static Helper class.

    Could you post the Helper.getTop() method?

    Thanks,

    Anthony

  • Anthony Candaele 1197 posts 2049 karma points
    Feb 12, 2013 @ 11:24
    Anthony Candaele
    0

    Hi Jeroen,

    No need for the getTop() Helper method. I extended the default Umbraco Navigation script, it was easier than I thought:

    @inherits umbraco.MacroEngines.DynamicNodeContext

    @{ 

    var level = String.IsNullOrEmpty(Parameter.Level) ? 1 : int.Parse(Parameter.Level); 

    var ulClass = String.IsNullOrEmpty(Parameter.UlClass) ? "" : String.Format(" class=\"{0}\"", Parameter.UlClass); 

    var parent = @Model.AncestorOrSelf(level);

    if (parent != null) {

    <[email protected](ulClass)>

    @foreach (var item in parent.Children.Where("Visible")) {

    var active = Array.IndexOf(Model.Path.Split(','), item.Id.ToString()) >= 0 ? " class=\"active\"" : "";

    <[email protected](active)>

    <a href="@item.Url">@item.Name</a>

                    @if(item.Children.Items.Count != 0){

                        var subpages = item.Children;

                        <ul>

                        @foreach (var subpage in subpages)

                        {

                            <li><a href="@subpage.Url">@subpage.Name</a></li>

                        }

                        </ul>

                    }

    </li>

    }

    </ul>

    }

    }

    Hope this might be of help to someone else

    greetings,

    Anthony

Please Sign in or register to post replies

Write your reply to:

Draft