Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Live Preview has issues when Eager Loading with {% do %} #5065

Closed
MarcHartwig13 opened this issue Oct 7, 2019 · 5 comments
Closed

Live Preview has issues when Eager Loading with {% do %} #5065

MarcHartwig13 opened this issue Oct 7, 2019 · 5 comments

Comments

@MarcHartwig13
Copy link

Description

I'm using {% do %} to eager load my entry information. I've had to create a work around for eager load matrix fields. I looked over issue #1787 but could only get my matrix blocks to display in live preview with the below work around. I'm also running into an issue with an entries field not display in live preview. Here is an implementation:

{% set eagerLoadedElements = [
    'featuredImage',
    'imageSlider',
    'venue',
    'featuredBusinesses',
    'listing',
    'gallery',
    'sponsorships',
    'sponsorships.sponsorLogo'
] %}

{% if not craft.app.request.getParam('x-craft-live-preview') %}
    {% set eagerLoadedElements = eagerLoadedElements|merge([
        'bodyContent',
        'bodyContent.image:image',
        'sidebarContent',
        'sidebarContent.itineraryDays:itineraryDays',
        'sidebarContent.activitiesNearby:activities',
    ]) %}
{% endif %}

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

Steps to reproduce

  1. Create a matrix block field
  2. Eager load in code with {% do craft.app.elements.eagerLoadElements() %}

Additional info

  • Craft version: 3.3.7
  • PHP version: 7.3.7
  • Database driver & version: MySQL 5.5.5
  • Plugins & versions:

Admin Bar: 3.1.8.1
Blitz: 2.3.0
Calendar: 2.0.24
Calendar Links: 1.0.1
Content Stats: 2.1.1
CP Field Inspect: 1.0.6
Dumper: 2.0.0
Element API: 2.6.0
Freeform: 3.3.2
Grid: 1.2.2
Guide: 1.4.0
Imager: v2.1.10
Image Resizer: 2.0.6
Minify: 1.2.9
Navigation: 1.1.13
Preparse Field: v1.1.0
Redactor: 2.4.0
SEO: 3.2.27
Store Hours: 2.1.1.1
Typed link field: 1.0.19
Typogrify: 1.1.18

@brandonkelly
Copy link
Member

Since you already have the entry, there is no performance benefit to eager-loading anything there except sponsorships.sponsorLogo. In fact you are going to get worse performance by eager-loading all those things.

And ever since Craft 3.2, you shouldn’t have to jump through any hoops like #1787 for Live Preview.

So all of your code there can be safely deleted, and whenever you are going to loop through sponsorships, that’s the point where you should eager-load the nested sponsorLogo field.

{% set sponsorships = entry.sponsorships
    .with(['sponsorLogo'])
    .all() %}

{% for sponsorship in sponsorships %}
    {% set sponsorLogo = sponsorship.sponsorLogo|first %}
    {% if sponsorLogo %}
        <img src="{{ sponsorLogo.url }}" alt="{{ sponsorLogo.title }}">
    {% endif %}
{% endfor %}

(Note that if sponsorships is a Matrix field, then the syntax should be with(['matrixBlockTypeHandle:sponsorLogo']) – see Eager-Loading Elements Related to Matrix Blocks.)

@MarcHartwig13
Copy link
Author

Thanks Brandon, I removed all of the eager loading as you suggested and noticed an increase in DB queries and response time for the queries. It was about 10 extra queries and 30 ms on average. So performance looks to be better while eager loading all the fields. This does resolve the live preview issue.

All the fields, in my example above, that are being eager loaded are relational fields. Asset fields, entries fields, and matrix fields. I believe I want to eager load all those types of elements as long as it results in a performance benefit. Is this a particular problem with me eager loading with {% do %}? Should I drop eager loading for asset fields and entries fields and only eager load using .with([]) on the matrix fields? I'm thinking I should stop using {% do %} all together? I may be just reiterating what you just said...

Sorry for my confusion on this and thanks for your help!

@brandonkelly
Copy link
Member

Sorry, it was a bit early when I replied and I overlooked what the middle chunk of your template is doing.

The bodyContent.image:image, sidebarContent.itineraryDays:itineraryDays, and sidebarContent.activitiesNearby:activities fields would also potentially benefit from eager-loading.

Should I drop eager loading for asset fields and entries fields and only eager load using .with([]) on the matrix fields? I'm thinking I should stop using {% do %} all together? I may be just reiterating what you just said...

{% do %} is just a general “execute something” tag; it’s not inherently related to eager loading or anything. It’s the call to craft.app.elements.eagerLoadElements() within it that is actually doing the eager-loading.

craft.app.elements.eagerLoadElements() maps to craft\services\Elements::eagerLoadElements(), which is the same method that the with element query param ends up calling internally. So it doesn’t matter which route you go, but generally with is recommended because it’s simpler.

So here’s the normal way you’d eager-load those fields:

bodyContent.image:image

{% set bodyContentBlocks = entry.bodyContent.with(['image:image']).all() %}
{% for block in bodyContentBlocks %}
    ...
{% endfor %}

sidebarContent.itineraryDays:itineraryDays and sidebarContent.activitiesNearby:activities

{% set sidebarContentBlocks = entry.sidebarContent.with([
    'itineraryDays:itineraryDays',
    'activitiesNearby:activities',
]).all() %}
{% for block in sidebarContentBlocks %}
    ...
{% endfor %}

Hope that all makes sense.

brandonkelly added a commit that referenced this issue Oct 12, 2019
@brandonkelly
Copy link
Member

While it’s still true that you shouldn’t eager-load Matrix blocks themselves when you already have the entry, it does turn out that there was a bug that prevented it from working. That has been fixed for the next release.

@MarcHartwig13
Copy link
Author

Thanks a bunch for looking into this further, appreciate it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants