Answers.Body: <p>Have you considered to cache the whole output? <a href="https://craftcms.com/docs/templating/cache" rel="nofollow noreferrer">https://craftcms.com/docs/templating/cache</a></p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-08-13T07:12:34.840Z
Answers.LastActivityDate: 2017-08-13T07:12:34.840Z
Answers.UserDisplayName: Tom Bauer
Answers.Body: <p>Caching will improve performance, but the actual issue is that your code is generating a lot of queries. You should look into eager loading:</p>
  
  <p><a href="https://craftcms.com/docs/templating/eager-loading-elements" rel="nofollow noreferrer">https://craftcms.com/docs/templating/eager-loading-elements</a></p>
  
  <p>The basic idea is that you predefine what sub-elements you're going to need (in your case gig_artist and gig_venue), so that Craft can preload them instead of loading them when Craft encounters them in your code (and do less efficient queries). </p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-08-15T03:37:40.557Z
Answers.Text: I have to admit I feel like a dummy—I read through the eager-loading docs before posting this and thought that technique wouldn't apply. But you made it clearer to me how Craft performs its queries. Eager-loading in my initial query (and changing my group filter from `all_shows|group('gig_artist.first()` to `all_shows|group('gig_artist[0]`) has got me back in a reasonable time frame.
Answers.UserDisplayName: Roger Wilco
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-08-15T07:22:13.620Z
Answers.Text: Yeah, I had the same experience a while ago. I thought it was something like lazy loading, before I really had a good look at it.
Answers.UserDisplayName: Youniteus
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-08-13T19:04:57.250Z
Answers.LastActivityDate: 2017-08-13T19:04:57.250Z
Answers.UserDisplayName: Youniteus
Body: <p>I have an event calendar of sorts for music gigs. The back-end has sections for Artists and Venues, where I enter appropriate info, and another section, Shows, which I choose an artist, a venue, and enter the event date (in a custom field).</p>
  
  <p>The template that pulls everything together grabs all future show dates, groups the dates by the artist, then checks each entry for fields before displaying it in the HTML, like so:</p>
  
  <pre><code>{#-- grab all current shows and order by date --#}
  {% set all_shows = craft.entries.section('shows').gig_date('&gt;=' ~ (now.date)).order('gig_date asc') %}
  
  {#-- group shows by artist --#}
  {% set artist_shows = all_shows|group('gig_artist.first()') %}
  
  {% for artist, shows in artist_shows %}
  
      {#-- artist title --#}
      &lt;h3&gt;{% if shows[0].gig_artist[0].artist_url|length %}&lt;a href="{{ shows[0].gig_artist[0].artist_url }}"&gt;{{ artist }}&lt;/a&gt;{% else %}{{ artist }}{% endif %}&lt;/h3&gt;
  
      &lt;table&gt;
          &lt;tbody&gt;
  
              {#-- shows list --#}
              {% for show in shows %}
  
                  &lt;tr&gt;
                      &lt;td class="gig_date"&gt;
  
                          {#-- date --#}
                          &lt;time title="{{ show.gig_date.w3c }}"&gt;{{ show.gig_date|date('F j') }}&lt;/time&gt;
                      &lt;/td&gt;
                      &lt;td class="gig_venue"&gt;
  
                          {#-- venue name and website--#}
                          {% if show.gig_venue[0].venue_url|length %}&lt;a href="{{ show.gig_venue[0].venue_url }}"&gt;{{ show.gig_venue[0].title }}&lt;/a&gt;{% else %}{{ show.gig_venue[0].title }}{% endif %}
  
                          {#-- city --#}  
                          {% if show.gig_venue[0].venue_city|length %}, {{ show.gig_venue[0].venue_city }}{% endif %}
  
                          {#-- state --#}
                          {% if show.gig_venue[0].venue_state|length %} {{ show.gig_venue[0].venue_state }}{% endif %}
  
                          {#-- notes --#}
                          {% if show.gig_notes|length %}&lt;div class="gig_notes"&gt;{{ show.gig_notes }}&lt;/div&gt;{% endif %}
                      &lt;/td&gt;
  
                  &lt;/tr&gt;
  
              {% endfor %}
          &lt;/tbody&gt;    
      &lt;/table&gt;
  
  {% endfor %}
  </code></pre>
  
  <p>This page takes several seconds to render on my site versus the other pages. I've tried this without the <code>|group</code> filtering, and without the date comparison, and it's still equally slow, which leads me to believe it's the pinging the multiple entry fields that's slowing things down.</p>
  
  <p>I have a hunch eager loading will be helpful, but unfortunately I can't wrap my brain around it at this level. Any ideas?</p>
  
Tags: <templating><entrymodel><eager-loading>
Title: How to improve performance of this nested entries/array template?
ThreadText: # How to improve performance of this nested entries/array template?
  
  (Asked by: username_0 on 2017-08-12)
  
  I have an event calendar of sorts for music gigs. The back-end has sections for Artists and Venues, where I enter appropriate info, and another section, Shows, which I choose an artist, a venue, and enter the event date (in a custom field).
  
  The template that pulls everything together grabs all future show dates, groups the dates by the artist, then checks each entry for fields before displaying it in the HTML, like so:
  
  ```
  {#-- grab all current shows and order by date --#}
  {% set all_shows = craft.entries.section('shows').gig_date('>=' ~ (now.date)).order('gig_date asc') %}
  
  {#-- group shows by artist --#}
  {% set artist_shows = all_shows|group('gig_artist.first()') %}
  
  {% for artist, shows in artist_shows %}
  
      {#-- artist title --#}
      <h3>{% if shows[0].gig_artist[0].artist_url|length %}<a href="{{ shows[0].gig_artist[0].artist_url }}">{{ artist }}</a>{% else %}{{ artist }}{% endif %}</h3>
  
      <table>
          <tbody>
  
              {#-- shows list --#}
              {% for show in shows %}
  
                  <tr>
                      <td class="gig_date">
  
                          {#-- date --#}
                          <time title="{{ show.gig_date.w3c }}">{{ show.gig_date|date('F j') }}</time>
                      </td>
                      <td class="gig_venue">
  
                          {#-- venue name and website--#}
                          {% if show.gig_venue[0].venue_url|length %}<a href="{{ show.gig_venue[0].venue_url }}">{{ show.gig_venue[0].title }}</a>{% else %}{{ show.gig_venue[0].title }}{% endif %}
  
                          {#-- city --#}  
                          {% if show.gig_venue[0].venue_city|length %}, {{ show.gig_venue[0].venue_city }}{% endif %}
  
                          {#-- state --#}
                          {% if show.gig_venue[0].venue_state|length %} {{ show.gig_venue[0].venue_state }}{% endif %}
  
                          {#-- notes --#}
                          {% if show.gig_notes|length %}<div class="gig_notes">{{ show.gig_notes }}</div>{% endif %}
                      </td>
  
                  </tr>
  
              {% endfor %}
          </tbody>    
      </table>
  
  {% endfor %}
  
  ```
  
  This page takes several seconds to render on my site versus the other pages. I've tried this without the `|group` filtering, and without the date comparison, and it's still equally slow, which leads me to believe it's the pinging the multiple entry fields that's slowing things down.
  
  I have a hunch eager loading will be helpful, but unfortunately I can't wrap my brain around it at this level. Any ideas?
  
  **Tags:** templating, entrymodel, eager-loading
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_2 on 2017-08-13. Score: 4 | Accepted answer
  
  Caching will improve performance, but the actual issue is that your code is generating a lot of queries. You should look into eager loading:
  
  <https://craftcms.com/docs/templating/eager-loading-elements>
  
  The basic idea is that you predefine what sub-elements you're going to need (in your case gig\_artist and gig\_venue), so that Craft can preload them instead of loading them when Craft encounters them in your code (and do less efficient queries).
  
  > **Comments:**
  > **username_0**: I have to admit I feel like a dummy—I read through the eager-loading docs before posting this and thought that technique wouldn't apply. But you made it clearer to me how Craft performs its queries. Eager-loading in my initial query (and changing my group filter from `all_shows|group('gig_artist.first()` to `all_shows|group('gig_artist[0]`) has got me back in a reasonable time frame.  
  > **username_2**: Yeah, I had the same experience a while ago. I thought it was something like lazy loading, before I really had a good look at it.  
  
  ---
  
  ### Answer by username_1 on 2017-08-13. Score: 4
  
  Have you considered to cache the whole output? <https://craftcms.com/docs/templating/cache>
  
  
  ---
  
  