
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.
Issue fork experience_builder-3522217
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 #3
mglamanNeeds 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.
Comment #5
phenaproximaAdded 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.
Comment #7
wim leersGreat 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: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:
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 😅🙈
Comment #8
wim leersRetitling for clarity.
Comment #9
wim leersFYI: #3520484: [META] Production-ready ComponentSource plugins's lists a whole sequence of kinda similar "now make it work correctly+well for live sites" remaining issues for the
BlockComponent
source!Comment #10
wim leersThis 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! 🥳Comment #11
isholgueras CreditAttribution: isholgueras at Acquia commentedComment #13
isholgueras CreditAttribution: isholgueras at Acquia commentedComment #14
wim leersComment #15
wim leersThis blocks #3523130 per #3523130-15: Auto-saved code component changes are not reflected in content preview and component library preview thumbnail.
Comment #16
wim leersComment #17
wim leers@mglaman and @penyaskito pointed something out that I missed: #3518185 forgot to update the cache tag logic of the JS component config entity.
Comment #18
wim leersComment #19
isholgueras CreditAttribution: isholgueras at Acquia commentedComment #20
wim leersGreat progress, almost ready! 😄
Comment #21
wim leersComment #22
wim leersJust needs MR conflicts resolved, but good to go now! 🤩
Comment #24
wim leersThanks! 😊 Very satisfying to see this resolved, great way to end the week!
Comment #25
wim leers