The Form That Loads Twice
A team deploys an Adaptive Form on AEM 6.5 (Service Pack 16) to a publish tier behind a dispatcher. The form uses a custom submit action that posts to an internal REST endpoint via a data source. Testers report that on first load the form renders in 4-6 seconds, but every subsequent navigation back to the form is fast. Dispatcher logs show the form HTML is never cached (Cache-Control: no-cache is set by the adaptive form servlet). The client also notices that form field values from a previous session sometimes appear. The AEM instance has two publish nodes; the dispatcher has a single farm with round-robin load balancing and no sticky sessions. The forms developer is asked to reduce perceived load time and eliminate stale-value leakage without changing the form's business logic.
1. Which architectural factor most likely explains the fast second load and the stale values, and what should be investigated first?
Read the worked answer
The pattern (slow first load, fast subsequent loads, stale values) points at client-side persistence and caching layers, not server rendering. Two suspects must be separated:
- Browser cache / back-forward cache (bfcache) - the form HTML is
no-cache, but the browser can still serve the document from bfcache on back navigation, which explains the fast return and can preserve DOM state including field values. - Adaptive Forms' own client-side state - draft/auto-save and the forms' local storage of data can repopulate fields.
Because the dispatcher does not cache the HTML, the server is not the cause of the fast second load. Investigate in this order: (a) confirm via DevTools whether the second load is a bfcache restore or a network request; (b) check whether the form has auto-save/draft enabled and where it persists; (c) check the data source's client-side caching headers. The round-robin/no-sticky detail matters for session-bound state, but stale field values that survive a fresh navigation are more consistent with client persistence than with server session affinity.
2. The team proposes enabling dispatcher caching of the form HTML to fix the first-load time. Evaluate this proposal.
Read the worked answer
Reject caching the raw adaptive form HTML. Reasons:
- The servlet explicitly sets
no-cache; overriding it at the dispatcher risks serving one user's prefill/state to another. Adaptive Forms can embed user-specific context (prefill data, authenticated headers, locale, theme variants). - With two publish nodes and no sticky sessions, a cached personalized document is a cross-user data leak, not just a performance bug.
- The 4-6s first load is more likely dominated by client-side JS/CSS bundle size, data source round-trips, or cold JVM/cache on publish than by HTML transfer.
Better levers: measure the waterfall to find the real bottleneck; reduce/async non-critical client libraries; warm publish caches after deployment; consider a CDN for static clientlibs only (which are safe to cache) while leaving the form document uncached. If caching is truly needed, it must be keyed on a cache-safe, non-personalized variant and validated against the no-sticky-session topology.
3. What concrete change addresses the stale-value symptom while preserving legitimate draft functionality?
Read the worked answer
Separate intentional draft restore from accidental state bleed:
- If draft/auto-save is a requirement, keep it but scope persistence to an authenticated user + form ID key, and clear it on successful submit. Verify the key includes user identity so two users on the same browser profile cannot collide.
- If draft is not a requirement, disable auto-save and ensure the form initializes from the data model on every load rather than from residual DOM/local storage.
- Add an explicit reset on the submit-success handler so a completed submission never repopulates.
Then re-test the back-navigation case specifically: if values persist only on bfcache restore, that is expected browser behavior and should be handled by a pageshow handler that re-initializes from the model when event.persisted is true. This keeps the fix in the form layer rather than fighting the browser or the dispatcher.