We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 26503
    • 620 Posts
    I have a site that I've been having some performance issues with for some time, I always thought it was wayfinder that was completely to blame, but now I'm wondering if it could be a misunderstanding of the uses of chunks within the templates themselves

    Here is the template, there are about 8 or so similar templates in use within the site, so I needed to keep things [callouts etc] in chunks & TVs for maintainability;

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    
    	[[$MetaHeaders]] <!-- calls a chunk of static html -->
    	
    	[[$ScriptHeaders]] <!-- calls some common js -->
    	
    	[[!If? &subject=`[[*LoadFlowPlayer]]` &operator=`eq` &operand=`true` &then=`[[$FlowplayerJS]]` ]] <!-- calls more js if flowplayer TV is set -->
    	
    	[[!*PPEnableScripts:is=`true`:then=`[[$PowerPointHeaders]]`]] <!-- calls more js if PowerPoint scripts are set -->
    	
    	[[$GoogleTranslate]] <!-- google translate code & js -->
    	
    	[[$GoogleAnalytics]] <!-- google analytics code -->
    
    </head>
    	<body>
    		
    		<div id="viewport" class="[[*ContentSection]]">
    		
    			<div id="log-in-bar">
    				<!-- calls the login stuff -->
    				[[!Login? &tplType=`modChunk` &preHooks=`ReturningUserAgreeToEULA` &loginTpl=`lgnCustomHeaderFormTpl` &logoutTpl=`lgnCustomLogoutTpl` &logoutResourceId=`216`  &loginResourceId=`0`]]
    			</div>
    			
    			<div id="header">
    				<div id="logo"><a href="/" ><img src="/assets/images/transparent.gif" height="117" width="243" border="0" /></a></div>
    				<div id="banner"></div>
    			</div>
    			
    			<div id="main-navigation">
    				<!-- navigation -->
    				[[Wayfinder? &debug=`0` &startId=`0` &level=`3` &displayStart=`1` &outerTpl=`MainOuterTpl` &rowTpl=`MainRowTpl` &parentRowTpl=`MainParentRow` &cacheResults=`1`]]
    			</div>
    			
    			<div id="breadcrumbs">
    				<!-- breadcrumbs -->
    				[[Breadcrumbs? &crumbSeparator=`>` &currentAsLink=`false` &titleField=`longtitle` &showCrumbsAtHome=`0`]]
    			</div>
    			
    			<!-- if this is the homepage, display the newsticket ~ calls getResources whch calls 2 more chunks -->
    			[[If? &subject=`[[*id]]` &operator=`==` &operand=`1` &then=`[[$ShowSlider]][[!$VerticalTicker]]`]]
    			
    			<div id="main-content">
    			
    				<div id="left-content">
    					<!-- this TV can call one of several chunks: Show Title &  Date Info==[[!$ShowFullPageTitle]]||Show Title Only==[[!$ShowOnlyTitle]]||Do Not Show Title==[[$ShowNoTitle]] -->
    					[[*ShowTitle]]
    					<!-- content -->
    					[[*content]] 
    					<!-- the PowerPointPageContent chunk will call get resources + gallery + several other chunks -->
    					[[!*PPEnableScripts:is=`true`:then=`[[$PowerPointPageContent]]`]]
    					<!-- if polls were enabled, will show poll feedback -->
    					[[*FeedbackID:notequalto=`0`:then=`[[$ShowPollFeedback]]`]]
    					<!-- enable polls or not -->
    					[[*allowComments]]
    	
    	
    				</div>
    				
    				<div id="right-content">
    					<!-- calls getresources which calls at least 2 other chunks [wrappper & row tpls] -->
    					[[!ShowOncologistSearch]]
    					<!-- if set calls getresources which calls at least 2 other chunks [wrappper & row tpls] -->
    					[[*CalloutPositionOne]]
    					<!-- if set calls getresources which calls at least 2 other chunks [wrappper & row tpls] -->
    					[[*CalloutPositionTwo]]
    					<!-- if set calls getresources which calls at least 2 other chunks [wrappper & row tpls] -->
    					[[*CalloutPositionThree]]
    					<!-- if set calls getresources which calls at least 2 other chunks [wrappper & row tpls] -->
    					[[*CalloutPositionFour]]
    					<!-- if set calls getresources which calls at least 2 other chunks [wrappper & row tpls] -->
    					[[*CalloutPositionFive]]
    				</div>
    						
    			</div>
    			
    			<div id="footer">
    				
    				<div id="footer-wrapper">
    				
    					<div id="footer-navigation">
    						<!-- calls a chunk of static html -->
    						[[$FooterNavigation]]
    					</div>
    					
    					<div id="footer-extras">
    						<!-- more static html -->
    						[[!$FooterExtras]]
    					</div>
    					<!-- chunk showing debug times -->
    					[[!$ShowDebugTime]]
    				
    				</div>
    				
    			</div>
    		
    		
    		</div>	
    	
    	</body>
    
    </html>
    
    



    The main navigation wayfinder call used to be in a chunk of it's own until I moved the call inside this template, I got nearly a second improvement in load times. So I've been wondering what the impact of calling multiple chunks in a cascading manner really is.... i.e. the TV [[*CalloutPositionFive]] gets replaced with a [user select-able] chunk which calls getResources which in turn calls two other chunks for it's wrapper & row tpls...

    In the end, this page loads in about 10 seconds [!!] when in cache it will load in about 3-4 seconds.

    Anyone have any thoughts, ideas or recommendations on best practices?

    -thanks
    -sean
      *** Not just websites, we also create signage, banners, print, trade show displays and more! ***

      Sean Kimball CLP, CLS.
      Technical Director / Sr. Developer | BigBlock Studios
      ._______________________________________________.
      Bigblock Studios http://www.bigblockstudios.ca Web site design & development.
      27-1300 King Street East. Box 167 Oshawa, Ontario L1H8J4 Canada.
      phone/fax: 905-426-5525
      • 36782
      • 109 Posts
      There are many with better understanding than I, but a couple observations:

      getResources is an excellent snippet, really second-to-none, IMHO -- but, I try and use it sparingly; because it's a very flexible, general purpose snippet, it's pretty demanding on server resources. I try to write my own simple snippets for very specific uses, and use getResources for the heavy lifting only. It has helped. For instance, my sidebar or footer "latest post" stuff, or rotating banner images, etc. always use a simple snippet which is about 5 - 15 lines of code.

      conditional logic is demanding. It can be tough to cut down on output modifiers, but with diligence I think you can find ways. Sometimes it's as simple as telling a client "no, sorry. You have to pick an image size and stick with it." smiley (yeah, easier said than done!)

      Template variables in getResources templates are killer. Try to get away from them wherever possible -- strange as it may sound, I have increased loading speed by using a snippet in a getResources template to check and process template variables, such as checking for images after it's been loaded, etc. -- , or:
      a) include but don't process them
      b) use the template variable group / process group parameters, which apparently saves some power.

      My final point is that if your page is cached I am surprised it's using 3 - 4 seconds.
      I sometimes use ySlow to check my sites; use google minify to crunch your css and js into minified arrays, use Yahoo smusher to crunch your images, and make sure you are calling Wayfinder and getResources cached (without the ! )

      And make sure your host isn't using CloudLinux !! sad

      OK, that last one might be less useful... but it would definitely be interesting to hear the server config.

        • 26503
        • 620 Posts
        It's a pretty standard MediaTemple DV3.0 running Modx 2.2.0, Centos 5.something, mysql 5.0.22 & php 5.2.5, the only thing I have done really was to bump the memory allocation to 128m via .htaccess, that's about it. I was running xcache at one point but found it caused problems with modx sites.

        I am having some success with including less calls to chunks in my templates [on other sites] but still I get that 2-4 second php lag on an uncached page [the current site I am working on loads first time 2-3 seconds then less than 1 second after being cached. ]

        I do use the chrome inspector to try and troubleshoot this, but generally the network info just shows the time to retrieve the page ~then~ the times to retrieve the other resources i.e. css, js, media etc.

        So maybe that clarifies my issue a little, that's somewhere between 2 & 4 seconds for php to parse the page THEN other resources still need to be downloaded. [on the other site below it's 10 seconds++]

        -sean
          *** Not just websites, we also create signage, banners, print, trade show displays and more! ***

          Sean Kimball CLP, CLS.
          Technical Director / Sr. Developer | BigBlock Studios
          ._______________________________________________.
          Bigblock Studios http://www.bigblockstudios.ca Web site design & development.
          27-1300 King Street East. Box 167 Oshawa, Ontario L1H8J4 Canada.
          phone/fax: 905-426-5525
          • 39333
          • 151 Posts
          You're doing more tedious things than I'm used to but right off what if you make a single chunk for the entire head section instead of calling 6 per template?
            MODX...the Zen of CMS
            "Bight off more than you can chew and keep right on chewing."
            • 26503
            • 620 Posts
            Quote from: eric.swd at Apr 06, 2012, 02:41 AM
            You're doing more tedious things than I'm used to but right off what if you make a single chunk for the entire head section instead of calling 6 per template?

            I have since trimmed down the number of calls in the head and footer [~marginal improvement] but I find it handy to be able to exclude/include different chunks in the head, the flowplayer and powerpoint headers for instance are only used on certain pages, occasionally even modifying the meta information is occasionally useful.

            My view of the whole template thing is that there should not be any html in it [well as little as possible] and use them for most of your processing.

            I am definitely finding that fewer chunks & fewer cascading chunks definitely does decrease the processing time. [oh. and learn to use the output modifiers instead of that little 'If' snippet ... seems to take much less processing!]
            [ed. note: sean69 last edited this post 14 years, 6 months ago.]
              *** Not just websites, we also create signage, banners, print, trade show displays and more! ***

              Sean Kimball CLP, CLS.
              Technical Director / Sr. Developer | BigBlock Studios
              ._______________________________________________.
              Bigblock Studios http://www.bigblockstudios.ca Web site design & development.
              27-1300 King Street East. Box 167 Oshawa, Ontario L1H8J4 Canada.
              phone/fax: 905-426-5525
              • 39333
              • 151 Posts
              It definitely gives me some new ideas and I'm glad you posted this. The way you implement it helps me, and others, advance our MODX usage. I find each time I implement MODX I change the way I do it and it's what I learn through this great community that propels that. It's like every time I think I am doing the best way possible I find 10 more new and better ways of using MODX. It's such a great CMS, truly infinitely customizable, as advertised.

              From what I've read BobRay saying in some other posts it sounds like maybe the developers have gotten carried away with the modularity which is now affecting performance. I think in the future they're going to reel that in some which should in effect help people, like yourself, who really push the usage limits in their deployments. Maybe he'll pop in here and make some genius suggestions for this. I know I'd love to read em.
                MODX...the Zen of CMS
                "Bight off more than you can chew and keep right on chewing."
                • 26503
                • 620 Posts
                Quote from: eric.swd at Apr 06, 2012, 12:21 PM
                It definitely gives me some new ideas and I'm glad you posted this. The way you implement it helps me, and others, advance our MODX usage.


                Thanks Eric!

                I certainly change things up a bit each time I do a new deployment as well, things are looking slightly different now, using less 'getresources', less 'if' and trying to use less chunk includes as well, which I am finding you can 'mitigate' somewhat as early as the design phase.

                Tweeted Bob, maybe he will chime in. smiley

                -sean
                  *** Not just websites, we also create signage, banners, print, trade show displays and more! ***

                  Sean Kimball CLP, CLS.
                  Technical Director / Sr. Developer | BigBlock Studios
                  ._______________________________________________.
                  Bigblock Studios http://www.bigblockstudios.ca Web site design & development.
                  27-1300 King Street East. Box 167 Oshawa, Ontario L1H8J4 Canada.
                  phone/fax: 905-426-5525
                  • 18373 ☆ A M B ☆
                  • 3,141 Posts
                  10 seconds is way too long... luckily I'm seeing chances to improve performance:

                  [[!If? &subject=`[[*LoadFlowPlayer]]` &operator=`eq` &operand=`true` &then=`[[$FlowplayerJS]]` ]] <!-- calls more js if flowplayer TV is set -->

                  => do not uncache the If snippet. Also, due to the recursive parsing you will find that the FlowplayerJS chunk is always processed (it works inside out) so this is kind of moot. Something like this would prevent that while retaining the functionality:
                  [[[[If? &subject=`[[*LoadFlowPlayer]]` &operator=`eq` &operand=`true` &then=`$FlowplayerJS`]]]]
                  


                  May look complicated, but see the links below (second one specifically) for more about it and why it works.

                  [[!*PPEnableScripts:is=`true`:then=`[[$PowerPointHeaders]]`]]

                  No point in uncaching a resource field. Again, could use the above trick more detailed in the second link below here to ignore the chunk if it's not neccessary to load.

                  <!-- if this is the homepage, display the newsticket ~ calls getResources whch calls 2 more chunks -->
                              [[If? &subject=`[[*id]]` &operator=`==` &operand=`1` &then=`[[$ShowSlider]][[!$VerticalTicker]]`]]

                  Again, the trick above could help.

                  Also, from your description the VerticalTicker chunk includes getResources - so why are you not caching the chunk there?! Cache what you can, and I do think this is cachable.

                  <!-- this TV can call one of several chunks: Show Title &  Date Info==[[!$ShowFullPageTitle]]||Show Title Only==[[!$ShowOnlyTitle]]||Do Not Show Title==[[$ShowNoTitle]] -->
                                      [[*ShowTitle]]

                  Make sure the chunks aren't uncached in your TV options either.

                  [[!*PPEnableScripts:is=`true`:then=`[[$PowerPointPageContent]]`]]

                  Again, no need to uncache resource fields. Same trick as above can apply here as well.

                  <!-- calls getresources which calls at least 2 other chunks [wrappper & row tpls] -->
                                      [[!ShowOncologistSearch]]

                  Again, don't uncache something that calls getResources, there's no point in that. getResources works with resources, and the cache is cleared when a resource is changed.

                  <!-- more static html -->
                                          [[!$FooterExtras]]

                  Cache the chunk too.


                  You say you've changed your template some bit, I'll gladly have a look at that as well if you post what it looks like now and see if I can pinpoint anything that you may want to try differently.


                  Here's two links to posts on my own blog which I wrote to help people understand when to cache items and when not to (the gist is: always cache). The first are general guidelines, the second deal with the more advanced techniques you can apply and to get a better understanding of how tags are parsed and in what order (which also explains the trick I showed above).

                  http://www.markhamstra.com/modx-blog/2011/10/caching-guidelines-for-modx-revolution/
                  http://www.markhamstra.com/modx-blog/2011/11/nested-caching-in-modx-revolution/
                    Mark Hamstra • Developer spending his days working on Premium Extras and a MODX Site Dashboard with the ability to remotely upgrade MODX and extras to make the MODX world a little better.

                    Tweet me @mark_hamstra, check my infrequent blog at markhamstra.com, my slightly more frequent ramblings at MODX.today or see code at Github.
                    • 4172
                    • 5,888 Posts
                    when using conditional output-filters
                    with then put always a :else to it.
                    This may speed it up a bit.

                    [[!*PPEnableScripts:is=`true`:then=`[[$PowerPointPageContent]]`:else=``]]


                    better than conditionals in your template is for this example to use input-options like that:

                    true==[[$PowerPointPageContent]]||false==


                    and put just the TV-Tag into the template:
                    [[*PPEnableScripts]]


                    This TV-tag should be cached, if possible.



                      -------------------------------

                      you can buy me a beer, if you like MIGX

                      http://webcmsolutions.de/migx.html

                      Thanks!
                      • 18373 ☆ A M B ☆
                      • 3,141 Posts
                      This TV-tag should be cached, if possible.
                      To emphasize that, there's no reason I can think of in regular usage to have TV or resource fields tags uncached.
                        Mark Hamstra • Developer spending his days working on Premium Extras and a MODX Site Dashboard with the ability to remotely upgrade MODX and extras to make the MODX world a little better.

                        Tweet me @mark_hamstra, check my infrequent blog at markhamstra.com, my slightly more frequent ramblings at MODX.today or see code at Github.