Overview

When modifying a JS Component and then publishing the changes, cache invalidation doesn't happen for pages which use that component. When logged in it may appear changed but the cache is still in page_cache or reverse proxies

Proposed resolution

\Drupal\experience_builder\Plugin\ExperienceBuilder\ComponentSource\JsComponent::renderComponent needs to add the JS component cacheable metadata to the build. This is already done in \Drupal\experience_builder\Plugin\ExperienceBuilder\ComponentSource\BlockComponent::renderComponent for the overrides JS component.

User interface changes

When browsing as an end user a live site that is powered by (changed) JS components, the end user will always see the latest published version of JS components.

Command icon 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

mglaman created an issue. See original summary.

mglaman’s picture

Status: Active » Needs work
Issue tags: +Needs tests

Needs tests. Normally I write a kernel test which implements CacheTagsInvalidatorInterface to track invalidations, so we could have a Page using a JS component. Then re-save the JS component and validate the cache tag invalidated.

But I suppose we could just render a page and verify the JS component cache tags are present now.

phenaproxima made their first commit to this issue’s fork.

phenaproxima’s picture

Added a basic set of assertions to prove that the JS component's cache metadata is added to the render array, but I'm leaving the "needs tests" tag here because we should still have coverage to prove that a nested component's cache tags are added.

wim leers’s picture

Great find, @mglaman! 🙏

Based on the issue summary, I expected our ComponentTreeHydratedTest to need updating. I'm pleased to see it does 👍


#3498889: ComponentSource plugin for code components is the issue that added the JsComponent source, and it did add the following expectation:

                                'tags' => ['config:experience_builder.component.js.my-cta'],

I just checked that issue + its MR for the substring "cach" and found no discussion about this. So we missed that in that >1000 net new LoC MR. 😞


Then, as @larowlan points out on the MR, #3500386: Code Components should render with their auto-saved state (if any) when rendered in the XB UI subsequently forgot to add \Drupal\experience_builder\AutoSave\AutoSaveManager::CACHE_TAG when appropriate.


And finally:

we should still have coverage to prove that a nested component's cache tags are added

Indeed, this is necessary since a few weeks; it's something we missed in #3518185: Store imported JS components in `JavaScriptComponent` (and reflect in config dependencies). It'd have been easier to spot if #3498889 didn't miss it originally.

Conclusion

We've been treating JS components ("code components") the same as other components sourced from simpler sources, but these are much more complex: they're assembled from 1 (now possibly multiple) config entities, and when rendered with isPreview: TRUE, they can be even be assembled from auto-save data (which could be changing any second)!

However, it was the reliance on separate CSS+JS URLs for auto-saved JS components that made this actually work fine inside XB's UI: all CSS/JS changes would be reflected correctly (and yes, those use Cache-Control: private, no-store). 👈 This worked fine, and is what all of us were dead-focused on 😇

This issue is specifically reporting that the cacheability metadata being missing is a problem when using the live (non-auto-saved) versions of code components, i.e. when browsing as an end user a live site that is powered by (changed) JS components! That's a crucial thing we haven't been spending enough brain cycles on 😅🙈

wim leers’s picture

Title: Components sourced from JsComponent are missing source component cacheable metadata » JsComponent-sourced rendered component instances lack cacheability of underlying config entities (+ auto-save tag when previewing)

Retitling for clarity.

wim leers’s picture

FYI: #3520484: [META] Production-ready ComponentSource plugins's Incomplete functionality → Correct rendering of components in a source: lists a whole sequence of kinda similar "now make it work correctly+well for live sites" remaining issues for the BlockComponent source!

wim leers’s picture

Issue tags: -Needs tests

This is well on its way — and a whole range of tests fail thanks to recent test infrastructure additions, which makes sense: \Drupal\Tests\experience_builder\Kernel\Plugin\ExperienceBuilder\ComponentSource\JsComponentTest::testRenderJsComponent()'s current expectations expect no cache tags; this changes that! 🥳

isholgueras’s picture

Assigned: Unassigned » isholgueras

tedbow made their first commit to this issue’s fork.

isholgueras’s picture

Assigned: isholgueras » Unassigned
Status: Needs work » Needs review
wim leers’s picture

Assigned: Unassigned » isholgueras
Status: Needs review » Needs work
wim leers’s picture

Status: Needs work » Reviewed & tested by the community
wim leers’s picture

Status: Reviewed & tested by the community » Needs work
Related issues:

@mglaman and @penyaskito pointed something out that I missed: #3518185 forgot to update the cache tag logic of the JS component config entity.

wim leers’s picture

Title: JsComponent-sourced rendered component instances lack cacheability of underlying config entities (+ auto-save tag when previewing) » JsComponent-sourced rendered component instances lack cacheability of underlying config entities (+ first-party imports + auto-save tag when previewing)
isholgueras’s picture

Assigned: isholgueras » wim leers
Status: Needs work » Needs review
wim leers’s picture

Assigned: wim leers » isholgueras
Status: Needs review » Needs work

Great progress, almost ready! 😄

wim leers’s picture

Issue tags: +beta blocker
wim leers’s picture

Status: Needs work » Reviewed & tested by the community

Just needs MR conflicts resolved, but good to go now! 🤩

  • wim leers committed 3fe03cc5 on 0.x authored by mglaman
    Issue #3522217 by isholgueras, wim leers, mglaman, phenaproxima,...
wim leers’s picture

Status: Reviewed & tested by the community » Fixed

Thanks! 😊 Very satisfying to see this resolved, great way to end the week!

wim leers’s picture

Assigned: isholgueras » Unassigned

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.