We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 1841
    • 141 Posts
    GetResources is a fantastic snippet however it isn't the fastest in the world, especially if you are using multiple calls on one page.

    At the moment I am using GetResources in 4 different areas of a page, even making sure that "includeTVs" and "Includecontent" are switched off this still results in a slow loading page. Caching does of course help but even so I'm thinking there much be a faster way to return this content.

    One of these GetReources displays the latest "Articles" content in a list of links, one displays a random image linked to the appropriate page, the third displays a random list of 15 linked images filtered by a TV and the last a chunk of the 8 most documents in a folder with menutitle=1.

    Any ideas how I could replace any of these with a faster custom snippet? any help would be most appreciated.
      • 32316
      • 387 Posts
      ... the 8 most documents in a folder with.
      I don't understand this!

      Any way I would first see which of the calls is slowing things down - perhaps only one or two of them are causing the problem.

      With that answered seeing the code of the calls might help determine the problem.
        • 1841
        • 141 Posts
        Sorry that should have been 8 most "recent" documents. There aren't any actual issues with the calls, it's just with having 4 seperate GetResources calls along with 2 small other snippets slows the page down so ideally replacing one or two (or even all) with custom snippets would hopefully speed things up a bit.

        Two of the calls only really need to get one element from each resource (the *alias), both however are set to sortby=()RAND and uncached (to generate random results).

        The get resources calls are:

        15 random results that are filtered by TV, this call only really needs the *alias from each document:
        [[!getResources?parents=`3,27` &depth=`4` &limit=`15` &tpl=`featured` &sortby=`RAND()` &tvFilters=`featuredbook==Yes` ]]


        8 most recent documents:
        [[getResources?parents=`3,27` &depth`=3` &limit=`8` &tpl=`reviews` &tplOdd=`reviews-alt` &sortBy=`pub_date` &sortdir=`DESC` &dateSource=`pub_date`]]


        1 Random:
        [[!getResources?parents=`3,27` &depth=`4` &tpl=`rand` &sortby=`RAND()` &limit=`1` ]]


        Latest News (from Articles area):
        [[getResources?parents=`30` &depth=`2` &limit=`10` &tpl=`news-list` &showHidden=`1` &sortBy=`pub_date` &sortdir=`DESC` ]]
          • 3749
          • 24,544 Posts
          I think you could gain a fair amount of speed by using a single custom snippet here, though whistlemaker's suggestion to profile the page is a good idea. I suspect that the first one is taking much of the time because of the &TVFilter property.

          A custom snippet could set placeholders for the four displays. In the examples above, #1 and #4 could easily be combined and done with a single query. And you could specify only the fields you need in each query.

          You'd also gain some speed (maybe a lot) if you could move the "featuredbook" data into an unused Resource field (e.g., introtext, description, longtitle) rather than having it as a TV. TVFilter searches can be very slow.


          ------------------------------------------------------------------------------------------
          PLEASE, PLEASE specify the version of MODX you are using.
          MODX info for everyone: http://bobsguides.com/modx.html [ed. note: BobRay last edited this post 14 years, 3 months ago.]
            Did I help you? Buy me a beer
            Get my Book: MODX:The Official Guide
            MODX info for everyone: http://bobsguides.com/modx.html
            My MODX Extras
            Bob's Guides is now hosted at A2 MODX Hosting
            • 1841
            • 141 Posts
            Thanks for the feedback guys, much appreciated. I've just tried using a standard field instead and it didn't actually make a big difference to the speed really.

            Any idea where I could learn to create a custom snippet?
              • 3749
              • 24,544 Posts
              This might give you a start on using xPDO to get objects like resources from the database: http://bobsguides.com/revolution-objects.html



              ------------------------------------------------------------------------------------------
              PLEASE, PLEASE specify the version of MODX you are using.
              MODX info for everyone: http://bobsguides.com/modx.html
                Did I help you? Buy me a beer
                Get my Book: MODX:The Official Guide
                MODX info for everyone: http://bobsguides.com/modx.html
                My MODX Extras
                Bob's Guides is now hosted at A2 MODX Hosting
                • 1841
                • 141 Posts
                Thanks for the help Bob, you are a star! I'll try and get my head round it!
                  • 1841
                  • 141 Posts
                  Hi Bob,

                  Ok I've created a custom snippet for the "latest news" based on your documentation and the example in the modx documentation however I can't figure out how to add extra options for things like "hidden from menu" and link_attribute=1 that can be overwritten in the snippet call on the page.

                  Am I doing this the best way so far (it's my first real attempt at a snippet):

                  <?php
                  $tpl = $modx->getOption('tpl',$scriptProperties,'menu-list');
                  $id = (int)$modx->getOption('id',$scriptProperties,30);
                  $c = $modx->newQuery('modResource');
                  $c->where(array(
                    'published' => true,
                    'deleted' => false,
                  ));
                  $children = $modx->getChildIds($id);
                  if (count($children) > 0) {
                      $c->where(array(
                          'id:IN' => $children,
                      ));
                  }
                  $c->sortby('publishedon','DESC');
                  $resources = $modx->getCollection('modResource',$c);
                   
                  $output = '';
                  foreach ($resources as $resource) {
                  if ($i < $limit) {
                      $resourceArray = $resource->toArray();
                      $output .= $modx->getChunk($tpl,$resourceArray);
                  }
                   $i++;
                  }
                  return $output;
                    • 1841
                    • 141 Posts
                    I think I've got most of it working but not sure if it's the best way to carry it out, what I've come up with is:
                    <?php
                    $limit = (isset($limit)) ? $limit : 10;
                    $showHidden = (isset($showHidden)) ? $showHidden : 1;
                    $featured = (isset($featured)) ? $featured : '';
                    $tpl = $modx->getOption('tpl',$scriptProperties,'menu-list');
                    $id = (int)$modx->getOption('id',$scriptProperties,30);
                    $c = $modx->newQuery('modResource');
                    $c->where(array(
                      'published' => true,
                      'deleted' => false,
                      'hidemenu' => $showHidden,
                      'link_attributes' => $featured,
                    ));
                    $children = $modx->getChildIds($id);
                    if (count($children) > 0) {
                        $c->where(array(
                            'id:IN' => $children,
                        ));
                    }
                    $c->sortby('publishedon','DESC');
                    $resources = $modx->getCollection('modResource',$c);
                     
                    $output = '';
                    foreach ($resources as $resource) {
                    if ($i < $limit) {
                        $resourceArray = $resource->toArray();
                        $output .= $modx->getChunk($tpl,$resourceArray);
                    }
                     $i++;
                    }
                    return $output;


                    Is this the most effective way?
                      • 22303 MODX Staff
                      • 10,725 Posts
                      This looks pretty good; just one note about using getCollection here. If the number of Resources will always be limited to a small number, this is fine, but getCollection loads the entire result set at once along with the xPDOObject instances corresponding to each row in the result set. This means all of those rows/objects are in memory at once.

                      It is much more efficient in terms of memory usage, unless you need to manipulate the collection before rendering output, to use getIterator(). This loads only one row and one xPDOObject instance into memory at a time when you loop over the xPDOIterator object.

                      Just replace the getCollection() call with getIterator() at line 21 in your code to take advantage of it:

                      $resources = $modx->getIterator('modResource',$c);