2

Using this snippet returns me 38 queries on my homepage without the Eager Beaver plugin.

{% do craft.app.elements.eagerLoadElements(
    className(entry),
    [entry],
    ['headerImage', 'image1', 'image2']
) %}

Without the above loading all three images with .one() gives me 33 queries.

Is this expected behavior or am I doing something wrong?

  • I'm not fully up to speed with Craft 3, but I don't understand why you are using the Twig do tag here in combination with that eagerLoadElements function. Have you taken a look at the Craft 3 documentation about eagerLoading? docs.craftcms.com/v3/dev/eager-loading-elements.html#app That has some great examples and explanation on how to do eager loading in Twig. – Tom De Smet Oct 3 '18 at 13:54
  • I know how to do eager loading, but I wanted to take it to the next level. Read more in this article about eager loading your entry. nystudio107.com/blog/…. – Thaoms Oct 4 '18 at 10:14
  • It would be helpful to get an answer to your question if you tell people that you're using a plugin. This isn't default Craft functionality nor syntax. It's the EagerBeaver plugin from NYStudio107. – Tom De Smet Oct 4 '18 at 11:58
  • I'm not using the plugin, this out of the box Craft now, but I guess that before you had to use a plugin. He explains that later in the article. Quote: Note that on Craft 3, you can do the exact same thing that the Eager Beaver plu­g­in does by using craft.app.elements.eagerLoadElements: – Thaoms Oct 4 '18 at 12:39
  • So are you actually using the entry. headerImage, etc. anywhere? If you do the query without eager loading, subsequent db queries are lazily evaluated, so they won't be triggered until you actually try to access a relation. – andrew.welch Oct 4 '18 at 13:44
3

I don't think eager loading will help in this case because you're trying to eager load fields with only a single relationship (asset). It's not the n+1 query problem eager loading is meant to solve.

If you had an asset field with multiple assets selected, you would see some benefit. But even then, if there are only a few assets, the small penalty of eager loading might not outweigh the small cost of queries for a few assets.

Bigger gains would come from nested relationships. For example, a set of related entries each with an asset for a thumbnail image.

{% do craft.app.elements.eagerLoadElements(
    className(entry),
    [entry],
    ['entriesField.image1']
) %}

{% for item in entry.entriesField %}
    {% set image = item.image1[0] ?? null %}
    {% if image %}
        {{ image.url }}
    {% endif %}
{% endfor %}

Also, it might be worth noting that in your testing, it matters what data you actually use.

In my test, this produced 19 queries:

{% set asset = entry.headerImage.one() %}
{{ asset.title }}

But this produced 23 queries:

{% set asset = entry.headerImage.one() %}
{{ asset.url }}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.