<p>Since you have two sections, you will need your two initial queries, however, in your example, although you are eager loading the children (<code>with(children)</code>), you are querying them a second time when doing <code>page.descendants.all()</code>.</p>
<p>Because you are doing this for every parent, things are adding up and you are hiting this high query count and speed issue.</p>
<p>First, your initial query should be:</p>
<pre class="lang-twig prettyprint-override"><code>{% set forIndividualsNavigation = craft.entries
    .section('servicesBusiness')
    .level(1)
    .with('children')
    .all() %}
</code></pre>
<p>Here, you fetch <code>level(1)</code> entries only and eager loading children on them. If you had more than 2 levels, you could use:</p>
<pre class="lang-twig prettyprint-override"><code>{% set forIndividualsNavigation = craft.entries
    .section('servicesBusiness')
    .level(1)
    .with('children.children')
    .all() %}
</code></pre>
<p>With this in place, your loop will look like below - I have stripped it down to a minimum so it can help others too but you should be able to adjust on your side:</p>
<pre class="lang-twig prettyprint-override"><code>&lt;ul&gt;
{# Loop over level 1 entries only #}
{% for page in forIndividualsNavigation %}
    &lt;li&gt;&lt;a href=&quot;{{ page.url }}&quot;&gt;{{ page.title }}&lt;/a&gt;
    {# Check if the current page has children, if so display #}
    {% if page.children %}
    &lt;ul&gt;
        {# Children are eager loaded so no need for `all()` again #}
        {% for page in page.children %}
            &lt;li&gt;
                &lt;a href=&quot;{{ page.url }}&quot;&gt;{{ page.title }}&lt;/a&gt;
            &lt;/li&gt;
        {% endfor %}
    &lt;/ul&gt;
    {% endif %}
    &lt;/li&gt;
{% endfor %}
&lt;/ul&gt;
</code></pre>
<p>Try this and you should see a drop in queries and a speed increase :)</p>
<p>If you need to order the children the way you were doing it in your original post, you can <a href="https://craftcms.com/docs/3.x/dev/eager-loading-elements.html#defining-custom-parameters-on-eager-loaded-elements" rel="nofollow noreferrer">pass custom params on the eager loaded elements</a> like so:</p>
<pre class="lang-twig prettyprint-override"><code>{% set forIndividualsNavigation = craft.entries
    .section('servicesBusiness')
    .level(1)
    .with([
        ['children', { orderBy: &quot;title ASC&quot; }]
    ])
    .all() %}
</code></pre>

CC BY-SA 4.0
2021-09-27T09:03:58.467Z
2021-09-30T09:59:02.903Z
2021-09-30T09:59:02.903Z
Oli
<p>So I am building a mega menu and a separate set of templates for mobile.
Both use the same set of element queries, which query two larger sections for pages and hierarchy. I am seeing quite slow load times (3-5 seconds) and I know it is down to the menus as when removed the site loads fast.</p>
<p><a href="https://i.sstatic.net/mUFu9.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/mUFu9.png" alt="enter image description here" /></a></p>
<p>I have done Eager loading and tried to optimise the queries, but inevitably I am using them twice across each template, so 4 times in total.</p>
<p>What is another/better more efficient method to do this?
I tried <code>clone()</code> function but I don't think i used it correctly.</p>
<p>For production, I could cache the menus so that would help, bit I would like to get to the bottom and improve the code and the performance of the queries initially.</p>
<p>Without positing lots of code, here is a summary of what I am doing.</p>
<p>First I setup two queries for the two main areas of the site.</p>
<pre><code>  {% set forIndividualsNavigation = craft.entries
    .section('servicesBusiness')
    .with('children') %}
  
  {% set forBusinessNavigation = craft.entries
    .section('servicesPersonal')
    .with('children') %}
</code></pre>
<p>Then within my mobile navigation templates, I have built a slide menu pattern that each level another menu slides in....</p>
<p><a href="https://i.sstatic.net/zf790.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/zf790.jpg" alt="enter image description here" /></a></p>
<p>This uses alpineJS and is setup like so in terms of queries.</p>
<pre><code> {% for page in forIndividualsNavigation.level(1).all() %}
    &lt;button
      class=&quot;hover:text-black hover:text-opacity-80 focus:text-brand-500 focus:outline-none // w-full flex items-center justify-between transition&quot;
    &gt;
      {{ page.title }}
      {{ svg('@icon/bx-line/bx-right-arrow-alt.svg')|attr({ class:&quot;w-7 h-7 flex-shrink-0 fill-current ml-2&quot; }) }}
    &lt;/button&gt;

&lt;div
  x-cloak
  x-show=&quot;{{ _xShow }}&quot;
  x-transition:enter=&quot;transition transform ease-out duration-200&quot;
  x-transition:enter-start=&quot;opacity-0 translate-x-full&quot;
  x-transition:enter-end=&quot;opacity-100 translate-x-0&quot;
  x-transition:leave=&quot;transition transform ease-in duration-300&quot;
  x-transition:leave-start=&quot;opacity-100 translate-x-0&quot;
  x-transition:leave-end=&quot;opacity-0 translate-x-full&quot;
  @click.away=&quot;{{ _xClose }}&quot;
  class=&quot;{{ panelClasses }}&quot;
&gt;
  &lt;button
    @click=&quot;{{ _xClose }}&quot;
    class=&quot;hover:underline focus:underline focus:outline-none // flex items-center transition mb-8&quot;
  &gt;
    {{ svg('@icons/bx-line/bx-arrow-back.svg')|attr({ class:&quot;w-5 h-5 mr-1 flex-shrink-0 fill-current&quot; }) }}
    &lt;span class=&quot;text-sm&quot;&gt;Back&lt;/span&gt;
  &lt;/button&gt;
 div&gt;
                &lt;a
                  href=&quot;{{ page.url }}&quot;
                  class=&quot;bg-business-900 p-4 -mx-6 font-semibold text-lg mb-2 block&quot;
                &gt;
                  {{ page.title }}
                &lt;/a&gt;
                
                &lt;ul class=&quot;divide-y divide-white divide-opacity-30 -mx-1&quot;&gt;
                  {% for page in page.descendants.orderBy('title ASC').all() %}
                    &lt;li&gt;
                      &lt;a href=&quot;{{ page.url() }}&quot;
                         class=&quot;text-white hover:text-black hover:text-opacity-80 hover:underline block py-3 px-1.5&quot;
                      &gt;
                        {{ page.title }}
                      &lt;/a&gt;
                    &lt;/li&gt;
                  {% endfor %}
                  
                  &lt;li&gt;
                    &lt;a href=&quot;{{ page.url }}&quot;
                       class=&quot;text-sm text-black text-opacity-80 hover:underline flex justify-between py-3 px-1.5 // border-t-2 border-white border-opacity-30&quot;
                    &gt;
                      Explore our {{ page.title }} practice
                      {{ svg('@icon/bx-line/bx-right-arrow-alt.svg')|attr({ class:&quot;w-5 h-5 flex-shrink-0 fill-current ml-2&quot; }) }}
                    &lt;/a&gt;
                  &lt;/li&gt;
                &lt;/ul&gt;
              &lt;/div&gt;
&lt;/div&gt;

</code></pre>
<p>Then the megu menus are setup like so:
<a href="https://i.sstatic.net/0m4Lh.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/0m4Lh.png" alt="enter image description here" /></a></p>
<pre><code>{% for page in forIndividualsNavigation.level(1).all() %}
  &lt;button
    class=&quot;text-base font-medium text-white flex px-1.5 w-full focus:outline-none&quot;
  &gt;
    &lt;div class=&quot;w-5 h-5 flex-shrink-0 mr-2 mt-px&quot; :class=&quot;childMenuIsOpen == {{ page.id }} ? 'bg-current ' : 'border border-current'&quot;&gt;&lt;/div&gt;
    {{ page.title }}
  &lt;/button&gt;
  
  &lt;div class=&quot;lg:px-4 2xl:px-8 mb-14 pt-3&quot;&gt;
    {% for page in forIndividualsNavigation.level(1).all() %}
      &lt;nav
      &gt;
        &lt;div class=&quot;flex&quot;&gt;
          &lt;div class=&quot;w-14&quot;&gt;
            &lt;div class=&quot;w-10 h-10  flex-shrink-0 bg-business-500 mb-2&quot;&gt;&lt;/div&gt;
          &lt;/div&gt;
          
          &lt;div class=&quot;flex-1 pt-2&quot;&gt;
            &lt;h3 class=&quot;font-semibold text-lead mb-3&quot;&gt;
              &lt;a href=&quot;{{ page.url() }}&quot; class=&quot;hover:underline&quot;&gt;{{ page.title }}&lt;/a&gt;
            &lt;/h3&gt;
            &lt;ul class=&quot;text-15 divide-y divide-gray-400 divide-opacity-30 -mx-1&quot;&gt;
              {% for page in page.descendants.orderBy('title ASC').all() %}
                &lt;li&gt;
                  &lt;a href=&quot;{{ page.url() }}&quot;
                     class=&quot;text-white text-opacity-60 hover:text-business-500 hover:bg-white hover:bg-opacity-10 hover:underline flex justify-between py-3 px-3&quot;
                  &gt;
                    {{ page.title }}
                    {{ svg('@icon/bx-line/bx-right-arrow-alt.svg')|attr({ class:&quot;w-5 h-5 flex-shrink-0 fill-current ml-2&quot; }) }}
                  &lt;/a&gt;
                &lt;/li&gt;
              {% endfor %}
              
              &lt;li&gt;
                &lt;a href=&quot;{{ page.url }}&quot; class=&quot;text-base text-business-500 hover:underline flex justify-between py-3 px-1.5 // border-t-2 border-gray-400 border-opacity-30&quot;&gt;
                  Explore our {{ page.title }} practice
                  {{ svg('@icon/bx-line/bx-right-arrow-alt.svg')|attr({ class:&quot;w-5 h-5 flex-shrink-0 fill-current ml-2 mr-2&quot; }) }}
                &lt;/a&gt;
              &lt;/li&gt;
            &lt;/ul&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/nav&gt;
    {% endfor %}
  &lt;/div&gt;
{% endfor %}

</code></pre>
<p>Please note that the code above is reduced as I have removed some divs and layout code to illustrate more the queries taking place and you can see from the screenshots why there are some duplicated query, as the layout is different and it toggles the child navigation as you click/hover.</p>

<templating><navigation><performance><queries>
Improve performance and element queries when used multiple times
# Improve performance and element queries when used multiple times

(Asked by: username_0 on 2021-09-25)

So I am building a mega menu and a separate set of templates for mobile.
Both use the same set of element queries, which query two larger sections for pages and hierarchy. I am seeing quite slow load times (3-5 seconds) and I know it is down to the menus as when removed the site loads fast.

I have done Eager loading and tried to optimise the queries, but inevitably I am using them twice across each template, so 4 times in total.
What is another/better more efficient method to do this?
I tried clone() function but I don't think i used it correctly.
For production, I could cache the menus so that would help, bit I would like to get to the bottom and improve the code and the performance of the queries initially.
Without positing lots of code, here is a summary of what I am doing.
First I setup two queries for the two main areas of the site.
  {% set forIndividualsNavigation = craft.entries
    .section('servicesBusiness')
    .with('children') %}
  
  {% set forBusinessNavigation = craft.entries
    .section('servicesPersonal')
    .with('children') %}

Then within my mobile navigation templates, I have built a slide menu pattern that each level another menu slides in....

This uses alpineJS and is setup like so in terms of queries.
 {% for page in forIndividualsNavigation.level(1).all() %}
    
      {{ page.title }}
      {{ svg('@icon/bx-line/bx-right-arrow-alt.svg')|attr({ class:"w-7 h-7 flex-shrink-0 fill-current ml-2" }) }}
    


  
    {{ svg('@icons/bx-line/bx-arrow-back.svg')|attr({ class:"w-5 h-5 mr-1 flex-shrink-0 fill-current" }) }}
    Back
  
 div>
                
                  {{ page.title }}
                
                
                
                  {% for page in page.descendants.orderBy('title ASC').all() %}
                    
                      
                        {{ page.title }}
                      
                    
                  {% endfor %}
                  
                  
                    
                      Explore our {{ page.title }} practice
                      {{ svg('@icon/bx-line/bx-right-arrow-alt.svg')|attr({ class:"w-5 h-5 flex-shrink-0 fill-current ml-2" }) }}
                    
                  
                
              



Then the megu menus are setup like so:

{% for page in forIndividualsNavigation.level(1).all() %}
  
    
    {{ page.title }}
  
  
  
    {% for page in forIndividualsNavigation.level(1).all() %}
      
        
          
            
          
          
          
            
              {{ page.title }}
            
            
              {% for page in page.descendants.orderBy('title ASC').all() %}
                
                  
                    {{ page.title }}
                    {{ svg('@icon/bx-line/bx-right-arrow-alt.svg')|attr({ class:"w-5 h-5 flex-shrink-0 fill-current ml-2" }) }}
                  
                
              {% endfor %}
              
              
                
                  Explore our {{ page.title }} practice
                  {{ svg('@icon/bx-line/bx-right-arrow-alt.svg')|attr({ class:"w-5 h-5 flex-shrink-0 fill-current ml-2 mr-2" }) }}
                
              
            
          
        
      
    {% endfor %}
  
{% endfor %}


Please note that the code above is reduced as I have removed some divs and layout code to illustrate more the queries taking place and you can see from the screenshots why there are some duplicated query, as the layout is different and it toggles the child navigation as you click/hover.

**Tags:** templating, navigation, performance, queries

---

## 1 answers

### Answer by username_1 on 2021-09-27. Score: 3 | Accepted answer

Since you have two sections, you will need your two initial queries, however, in your example, although you are eager loading the children (with(children)), you are querying them a second time when doing page.descendants.all().
Because you are doing this for every parent, things are adding up and you are hiting this high query count and speed issue.
First, your initial query should be:
{% set forIndividualsNavigation = craft.entries
    .section('servicesBusiness')
    .level(1)
    .with('children')
    .all() %}

Here, you fetch level(1) entries only and eager loading children on them. If you had more than 2 levels, you could use:
{% set forIndividualsNavigation = craft.entries
    .section('servicesBusiness')
    .level(1)
    .with('children.children')
    .all() %}

With this in place, your loop will look like below - I have stripped it down to a minimum so it can help others too but you should be able to adjust on your side:

{# Loop over level 1 entries only #}
{% for page in forIndividualsNavigation %}
    {{ page.title }}
    {# Check if the current page has children, if so display #}
    {% if page.children %}
    
        {# Children are eager loaded so no need for `all()` again #}
        {% for page in page.children %}
            
                {{ page.title }}
            
        {% endfor %}
    
    {% endif %}
    
{% endfor %}


Try this and you should see a drop in queries and a speed increase :)
If you need to order the children the way you were doing it in your original post, you can pass custom params on the eager loaded elements like so:
{% set forIndividualsNavigation = craft.entries
    .section('servicesBusiness')
    .level(1)
    .with([
        ['children', { orderBy: "title ASC" }]
    ])
    .all() %}


---

