Problem/Motivation
The MailchimpSignupSubscribeBlock directly embeds a form using $this->formBuilder->getForm() in its build() method. Forms contain unique security tokens (form_build_id and form_token) that must be generated fresh on every request, which prevents Dynamic Page Cache from caching any page containing this block.
This impacts site performance, as pages with the subscribe block cannot be served from Dynamic Page Cache, requiring full rendering on every page load.
Steps to reproduce
- Place a Mailchimp Signup block on a page
- Enable Dynamic Page Cache module
- Check response headers - you'll see
X-Drupal-Dynamic-Cache UNCACHEABLE (poor cacheability)on every request - The page is never cached due to the form tokens
Proposed resolution
Convert the form rendering to use a lazy builder, which allows the block content to be cached while the form (with its unique tokens) is rendered as a placeholder after cache retrieval.
Issue fork mailchimp-3559374
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
loze commentedComment #3
loze commentedComment #5
loze commentedComment #6
xenophyle commentedThanks for the MR! I made some suggestions.
Comment #7
loze commented@xenophyle, I have made some changes addressing your comments.
The one outstanding issue would be, do we want to leave the static lazy builder callback in the function with \Drupal::service() calls
Or would you rather create a new lazy builder service, where we can use dependency injection, and move the callback to there?
Comment #8
loze commentedPerhaps it should be a service, this way we could lazy load both the block and page forms using the same service.
Comment #9
loze commentedOk, so I ended up making the lazy builder service and and using it on both the block and page forms.
This should be ready for review now.
Comment #10
xenophyle commentedLooks like this works now, thanks!