Problem/Motivation
The Rendered entity field adds cache tags for a all entity display config entities associated with the entity type of the rendered entity. In other words, if the content (node) view is configured to display a Rendered entity field, the cache tags for all configured entity view displays for node types will be added to the view/view display config's cache metadata. On a site with many content types and entity displays/view modes, this will bubble up all those cache tags on pages where the view is rendered. This can lead to errors such as #2844620: Automatically split cache debug headers into multiple lines when they exceed 8k.
Since rendering the entity will bubble up cache tags that are invalidated whenever entity view displays are saved, it is not necessary for the Rendered Entity plugin to include cache tags for the entity view displays in getCacheTags() at all.
Steps to reproduce
- Create a few different content types
- Create a few different view modes for content
- Configure custom displays for some view modes across content types
- Create and configure a view to display content with a Rendered entity field. Add a filter for a single content type
- Create test content that will be displayed in the view
- Visit page with the view.
- If
http.response.debug_cacheability_headersis true, note that there are tags in the HTTP header for all configured node entity displays. - Alternatively check the relevant entry in the cache_page database table and observe the tags there
Proposed resolution
Change getCacheTags() in \Drupal\views\Plugin\views\field\RenderedEntity to return an empty array.
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|
Issue fork drupal-3187770
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
godotislateHere's a patch where
getCacheTags()returns an empty array to see how it does against tests.Comment #4
godotislateI discovered that the entity render array does not have the entity view display config as a cache tag that bubbles up, unless the Layout Builder module is enabled. In that case, next step will be to amend the patch to include cache tags for the selected view mode. Update patch and tests hopefully soon.
Comment #7
godotislateComment #8
godotislateComment #9
godotislateComment #15
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #17
godotislateRebased MR against 11.x and tweaked some comment language.
Comment #18
smustgrave commentedSeems test-only feature was ran
Change itself makes sense and I don't see any issue myself.
Good work!
Comment #19
catchI am probably missing something but I feel like I need to ask:
::render does this:
This should add the entity display cache tags to the rendered, output anyway - isn't that enough?
Comment #20
godotislate@catch I vaguely recall having a similar thought when I originally ran into this three years ago, and then discovering that the tags still needed to be identified in the plugin
getCacheTags()code. If so, I don't remember why, so I'll have to look into it again and refresh my memory.ETA. Never mind, the strikeout text in the IS talks about this. And my comment #4 says that those display cache tags aren't bubbling up? I will re-confirm.
Comment #21
catchI feel like we fixed some of that in #2381217: Views should set cache tags on its render arrays, and bubble the output's cache tags to the cache items written to the Views output cache and #2381277: Make Views use render caching and remove Views' own "output caching" but also issues like this and others are making me think maybe we didn't finish the job.
Comment #22
godotislateI investigated some and found a couple things.
First, I installed Drupal with standard profile against latest 11.x-dev (#840a726). Then I set
http.response.debug_cacheability_headers: true. I created and saved an article node, and viewed the cache tags in the page response, which are these:block_view config:block.block.olivero_account_menu config:block.block.olivero_breadcrumbs config:block.block.olivero_content config:block.block.olivero_help config:block.block.olivero_main_menu config:block.block.olivero_messages config:block.block.olivero_page_title config:block.block.olivero_powered config:block.block.olivero_primary_admin_actions config:block.block.olivero_primary_local_tasks config:block.block.olivero_search_form_narrow config:block.block.olivero_search_form_wide config:block.block.olivero_secondary_local_tasks config:block.block.olivero_site_branding config:block.block.olivero_syndicate config:block_list config:search.settings config:system.menu.account config:system.menu.main config:system.site config:user.role.anonymous http_response local_task node:1 node_view rendered user:1. The cache tag for the entity view display is not included.Next, I installed Layout Builder, but did not configure any entity view displays to use it. Reloading the article node, the cache tags are these:
block_view config:block.block.olivero_account_menu config:block.block.olivero_breadcrumbs config:block.block.olivero_content config:block.block.olivero_help config:block.block.olivero_main_menu config:block.block.olivero_messages config:block.block.olivero_page_title config:block.block.olivero_powered config:block.block.olivero_primary_admin_actions config:block.block.olivero_primary_local_tasks config:block.block.olivero_search_form_narrow config:block.block.olivero_search_form_wide config:block.block.olivero_secondary_local_tasks config:block.block.olivero_site_branding config:block.block.olivero_syndicate config:block_list config:core.entity_view_display.node.article.default config:search.settings config:system.menu.account config:system.menu.main config:system.site config:user.role.anonymous http_response local_task node:1 node_view rendered user:1. The entity view display tag now is included.Doing a little debugging, from what I can tell, the
isApplicable()method inDrupal\layout_builder\Plugin\SectionStorage\OverridesSectionStorageandDrupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorageis adding the entity view display as cacheable dependency. Otherwise without Layout Builder enabled, the entity render array does not bubble any entity view display cache tags. Should there be an issue to add the entity view display as a cacheable dependency in\Drupal\Core\Entity\EntityViewBuilder::getBuildDefaults()or similar?On the Views side, I noticed this in the docblock for
Drupal\views\Entity\View::addCacheMetadata():So, even if the entity render array does bubble the view display cache tags, it might still make sense to compute them in
RenderedEntity::getCacheTags()so they get saved to the view config.Comment #23
catchThis is what I think is probably outdated though - if the cache tags are bubbled, we don't need to ask the plugins explicitly for them at all.
Something like that sounds good to me yes.
Comment #24
godotislateAfter some digging:
In
Drupal\Core\Entity\Entity\EntityViewDisplay::postSave(), the entity view builder resets its cache, which means it invalidates everything tagged with{ENTITY_TYPE_ID}_view, where {ENTITY_TYPE_ID} is the ID of the entity type the view display is for. (So saving a entity view display for a node type will invalidate cached items tagged withnode_view). In this case, is it necessary to even include entity view display cache tags at all? The {ENTITY_TYPE_ID}_view tag does get bubbled, so to the original raised question, it doesn't seem necessary for the Rendered Entity plugin at least to include any entity view display cache tags.This does raise a separate question: is invalidating
{ENTITY_TYPE_ID}_viewtoo broad on an entity view display save? If we do add tags for entity view displays to entity render arrays, should it be enough for the view display tags be invalidated and not invalidate{ENTITY_TYPE_ID}_view? Not sure of the ramifications for what seems to be a pretty significant change.In any event, moving this back to needs work to update MR and Issue to reflect solution of not including display cache tags via the plugin.
Comment #25
godotislateUpdated MR to so that the RenderedEntity plugin returns empty array for
getCacheTags()and rebased.Updated IS to reflect new solution.
Comment #26
smustgrave commentedRebased to run test-only feature
Issue summary seems complete and code change is small for the cache tags and has a good comment explaining why it's empty array.
Note rebase failure is a random nightwatch or javascript depending when you look at it.
Comment #27
catchIt's quite a rare operation especially on production sites and it reduces the necessary cache tags by a lot, so for me it's the right balance yeah.
Comment #28
quietone commentedI'm triaging RTBC issues. I read the IS and the comments. @godotislate, thanks for working on this and the investigative work done.
There is good discussion and explanation of the problem in #19 -> #24.
In #23 catch commented that a follow up issue is needed. I am adding the tag and setting this to needs work for that followup.
Also in #23 catch asked if the doc block for Drupal\views\Entity\View::addCacheMetadata() is outdated. That also needs some investigation, which can be in a separate issue. Although, maybe there already is one?
I did not read the MR or test it.
Comment #29
godotislatePer conversation with catch on Slack, because the ENTITY_TYPE_view cache tags are invalidated on entity view display save (see #24), there is no need to invalidate the individual cache tag for the display itself.
Created follow-up issue for the docblock in Drupal\views\Entity\View::addCacheMetadata(): https://www.drupal.org/project/drupal/issues/3409816
Moving this back to RTBC.
Comment #30
godotislateAdded post update hook with tests to update existing view configurations to remove rendered entity cache tags.
Comment #31
smustgrave commentedAddition of update hook seems fine, ran locally without issue at least.
Comment #32
catchQuestion on the MR.
Comment #33
godotislateMade changes per review question and rebased.
Comment #34
smustgrave commentedFeedback appears to have been addressed.
Reviewed commits https://git.drupalcode.org/project/drupal/-/merge_requests/170/diffs?com... and https://git.drupalcode.org/project/drupal/-/merge_requests/170/diffs?com... for the feedback jsut FYI.
Comment #35
catchThis looks good but it needs a rebase.
Comment #36
godotislateRebased for merge conflict.
Comment #38
catchCommitted/pushed to 11.x (which will become 10.3.x too), thanks!