We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 48586
    • 78 Posts
    rjohnson375 Reply #1, 9 years ago
    I have a very data-heavy page on my site, and the load time is terrible. I'm pretty sure AJAX is the answer, I'm just having a difficult time wrapping my head around a solution. Any help would be greatly appreciated.

    Here is a sample layout of my page, I have 5 tabs for levels of hotels, under each tab are up to 900 results. Currently it is loading the data for all 5 tabs and causing a 12 second page load time, which is terrible. I tested with just one tab loading a query and that is around 3 seconds.

    ----------------------------------------------------------------------------------
                               5 Star     4 Star     3 Star     2 Star     1 Star
    
    Hotel Name                 Pool       Valet Parking      Pet-friendly
    29 Inn                        Yes        No                 Yes
    4 Seasons                     Yes        Yes                No
    etc...



    My filter tabs are very basic:

    <ul class="hotel-star-level">
    <li><a href="#5star">5 Star</li>
    <li><a href="#4star">4 Star</li>
    <li><a href="#3star">3 Star</li>
    <li><a href="#2star">2 Star</li>
    <li><a href="#1star">1 Star</li>
    </ul>


    My resource runs through the tabs (5 Star, 4 Star, etc), each one is a div with a snippet that performs the query:

    <div class="tab-content-wrap">
              
    <!-- Tab 1 -->
    <div id="all" class="first pill-tab-content">
      <div class="hotel-rows-wrap">
        [[hotel_listing_rows? &filter=`all`]]
      </div><!-- / .hotel-rows-wrap -->
    </div><!-- / #tab-1 -->
    
    <!-- Tab 2 -->          
    <div id="5star" class="pill-tab-content">
      <div class="hotel-rows-wrap">
        [[hotel_listing_rows? &filter=`5star`]]
      </div><!-- / .hotel-rows-wrap -->
    </div><!-- / #tab-2 -->
    
    etc..


    The hotel_listing_rows snippet is basically a switch that runs through all the cases of filter, and performs a query to display the content.

    Ideally to minimize page load time I think each tab needs to dynamically change the filter on my snippet, and from what I've been reading JQuery and AJAX seem to be the answer, but I am having a hard time figuring out how to implement that. Please help, thank you.
      • 4172
      • 5,888 Posts
      Why do you want to load 900 results into one page.
      Nobody wants to see 900 Hotels at once.
      Can't you make one page(resource) for each tab and paginate the results of each tab or load them with infinit scroll or something?
        -------------------------------

        you can buy me a beer, if you like MIGX

        http://webcmsolutions.de/migx.html

        Thanks!
        • 48586
        • 78 Posts
        rjohnson375 Reply #3, 9 years ago
        Quote from: Bruno17 at Apr 17, 2015, 03:33 PM
        Why do you want to load 900 results into one page.
        Nobody wants to see 900 Hotels at once.
        Can't you make one page(resource) for each tab and paginate the results of each tab or load them with infinit scroll or something?

        I am just using hotels as an example, probably a very extreme example haha, but the data I am returning does need to be on a single page. Maybe 900 is high, let's say 5-600 results. I am looking into infinite scroll, thank you.
          • 3749
          • 24,544 Posts
          Press Ctrl-shift-i in Chrome or Firefox and check the process on the Timeline or Performance tab. That will tell you what's using up the time.

          If you're on shared hosting, you may just be querying an overloaded server. That said, collecting and displaying that much data is going to take some time.

          Using JQuery and Ajax might be even slower, since you'll be adding the JS rendering time on top of the query time.

          If you post your snippet code, we might spot some inefficiencies. For starters, if your first tab is always going to show all of them, you should try only making one query to the DB and building the other tabs by filtering the returned data (preferably making one pass through the data and building all the tabs as you go).
            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
            • 48586
            • 78 Posts
            rjohnson375 Reply #5, 9 years ago
            Thank you BobRay, that sounds like a great idea, I think my issue is that I am running a query for each filter, and not sure how to run one query then filter the remaining data (might end up being something as simple as running my query outside my switch), here is part of my snippet code to give a general idea on how I am pulling it.

            <?php
            $path = MODX_CORE_PATH . 'components/name-of-component/';
            $result = $modx->addPackage('name-of-component',$path .
                'model/','TABLEPREFIX_');
            
            if (! $result) {
                return 'failed to add package';
            } else {
            switch ($filter) {
                
            // Filters
            
            case "all":
            $query = $modx->newQuery('TABLESUFFIX');
            $query->sortby('listing_number');
            
            $listings = $modx->getCollection('TABLESUFFIX', $query);
            
            foreach($listings as $listing) {
                $fields = $listing->toArray();
                if ($listing->get('basic') == '1') {
                    $fields['basic_check'] = '<img src="assets/images/icons/check.svg" alt="" width="20" height="20">';
                } else {
                    $fields['basic_check'] = '';
                }
                if ($listing->get('basic2') == '1') {
                    $fields['basic2_check'] = '<img src="assets/images/icons/check.svg" alt="" width="20" height="20">';
                } else if ($listing->get('basic2') == '2') {
                    $fields['basic2_check'] = '<img src="assets/images/icons/dollar.svg" alt="" width="20" height="20">';
                } else {
                    $fields['basic2'] = '';
                }
                if ($listing->get('basic3') == '1') {
                    $fields['basic3_check'] = '<img src="assets/images/icons/check.svg" alt="" width="20" height="20">';
                } else if ($listing->get('basic3') == '2') {
                    $fields['basic3_check'] = '<img src="assets/images/icons/dollar.svg" alt="" width="20" height="20">';
                } else {
                    $fields['basic3_check'] = '';
                }
                $output .= $modx->getChunk('listings_row', $fields);
            };
            return $output;
            break;
            
            case "filter-tab-2":
            $query = $modx->newQuery('TABLESUFFIX');
            $query->where(array(
              listing_type => 'filter-tab-2'
            ));
            $query->sortby('listing_number');
            
            $listings = $modx->getCollection('TABLESUFFIX', $query);
            
            foreach($listings as $listing) {
                $fields = $listing->toArray();
                if ($listing->get('basic') == '1') {
                    $fields['basic_check'] = '<img src="assets/images/icons/check.svg" alt="" width="20" height="20">';
                } else {
                    $fields['basic_check'] = '';
                }
                if ($listing->get('basic2') == '1') {
                    $fields['basic2_check'] = '<img src="assets/images/icons/check.svg" alt="" width="20" height="20">';
                } else if ($listing->get('basic2') == '2') {
                    $fields['basic2_check'] = '<img src="assets/images/icons/dollar.svg" alt="" width="20" height="20">';
                } else {
                    $fields['basic2'] = '';
                }
                if ($listing->get('basic3') == '1') {
                    $fields['basic3_check'] = '<img src="assets/images/icons/check.svg" alt="" width="20" height="20">';
                } else if ($listing->get('basic3') == '2') {
                    $fields['basic3_check'] = '<img src="assets/images/icons/dollar.svg" alt="" width="20" height="20">';
                } else {
                    $fields['basic3_check'] = '';
                }
                $output .= $modx->getChunk('listings_row', $fields);
            };
            return $output;
            break;
            
            case "filter-tab-3":
            $query = $modx->newQuery('TABLESUFFIX');
            $query->sortby('listing_number');
            
            $listings = $modx->getCollection('TABLESUFFIX', $query);
            
            foreach($listings as $listing) {
                $fields = $listing->toArray();
                if ($listing->get('basic') == '1') {
                    $fields['basic_check'] = '<img src="assets/images/icons/check.svg" alt="" width="20" height="20">';
                } else {
                    $fields['basic_check'] = '';
                }
                if ($listing->get('basic2') == '1') {
                    $fields['basic2_check'] = '<img src="assets/images/icons/check.svg" alt="" width="20" height="20">';
                } else if ($listing->get('basic2') == '2') {
                    $fields['basic2_check'] = '<img src="assets/images/icons/dollar.svg" alt="" width="20" height="20">';
                } else {
                    $fields['basic2'] = '';
                }
                if ($listing->get('basic3') == '1') {
                    $fields['basic3_check'] = '<img src="assets/images/icons/check.svg" alt="" width="20" height="20">';
                } else if ($listing->get('basic3') == '2') {
                    $fields['basic3_check'] = '<img src="assets/images/icons/dollar.svg" alt="" width="20" height="20">';
                } else {
                    $fields['basic3_check'] = '';
                }
                $output .= $modx->getChunk('listings_row', $fields);
            };
            return $output;
            break;
            [ed. note: rjohnson375 last edited this post 9 years ago.]
              • 4172
              • 5,888 Posts
              this might be a little bit faster:

              $query = $modx->newQuery('TABLESUFFIX');
              $query->sortby('listing_number');
              $listings = array();
              if ($query->stmt->execute()) {
                  if (!$listings = $c->stmt->fetchAll(PDO::FETCH_ASSOC)) {
                      $listings = array();
                  }
              }
              
              foreach($listings as $fields) {
                  if ($fields['basic'] == '1') {
                      $fields['basic_check'] = '<img src="assets/images/icons/check.svg" alt="" width="20" height="20">';
                  } else {
                      $fields['basic_check'] = '';
                  }
                  if ($fields['basic2'] == '1') {
                      $fields['basic2_check'] = '<img src="assets/images/icons/check.svg" alt="" width="20" height="20">';
                  } else if ($fields['basic2'] == '2') {
                      $fields['basic2_check'] = '<img src="assets/images/icons/dollar.svg" alt="" width="20" height="20">';
                  } else {
                      $fields['basic2'] = '';
                  }
                  if ($fields['basic3'] == '1') {
                      $fields['basic3_check'] = '<img src="assets/images/icons/check.svg" alt="" width="20" height="20">';
                  } else if ($fields['basic3'] == '2') {
                      $fields['basic3_check'] = '<img src="assets/images/icons/dollar.svg" alt="" width="20" height="20">';
                  } else {
                      $fields['basic3_check'] = '';
                  }
                  $output .= $modx->getChunk('listings_row', $fields);
              };
              



              if it really needs to be all in one page and you want to load the other filtered items by ajax, you have to create a new resource with an empty template and put a snippet on it, which does return the items depending on the ajax request-params [ed. note: Bruno17 last edited this post 9 years ago.]
                -------------------------------

                you can buy me a beer, if you like MIGX

                http://webcmsolutions.de/migx.html

                Thanks!
                • 48586
                • 78 Posts
                rjohnson375 Reply #7, 9 years ago
                Great, thank you very much Bruno17, I'll update my code, this looks like it will decrease the page load time