Skip to content

fix(useSection): key lazy-section cache on block content, not release revision - #1243

Draft
pedrofrxncx wants to merge 1 commit into
mainfrom
fix/content-addressed-render-cb
Draft

pedrofrxncx wants to merge 1 commit into
mainfrom
fix/content-addressed-render-cb

Conversation

@pedrofrxncx

@pedrofrxncx pedrofrxncx commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Why

useSection builds the /deco/render URL with __cb = hash(release revision, vary, href, deploymentId). The release revision changes on every CMS publish, even a decofile-only publish that doesn't redeploy. So every publish changes the URL of every lazy section on every page, and the CDN entries already warm under max-age=300, stale-while-revalidate=3600 are thrown away.

Measured on miess-01 (2026-10-13, 10:00–21:00Z, Cloudflare logs for www.miess.com.br):

  • 33 publishes in bursts. Only 1 of them redeployed; the rest were decofile-only hot-reloads.
  • /deco/render hit rate was about 33–41% in quiet windows and fell to 13–20% during publish bursts.
  • Misses where the same render URL minus __cb had been requested in the previous 65 minutes under a different __cb:
    • ~72.8k of 174k render misses (~42%), about 364 MB of origin egress plus 72.8k extra origin SSR renders.
    • 7–12k per hour in burst hours, against about 400 per hour with no publishes.
    • That's roughly 3k extra origin renders and ~15 MB per publish.
  • Most of those keys are PDP/PLP lazy sections whose own page didn't change. A home banner publish invalidated all of them.

What

The global revision is replaced with a content version: a hash of the named blocks (resolvable entries) on the section's resolve chain, for example pages-category-…, plus any named section block the section is resolved through.

  • Block hashes are memoized per block object. Decofile providers replace changed blocks with freshly parsed objects and keep identity for unchanged ones; no in-place mutation.
  • If the chain has no named block, it falls back to the revision, so behavior is the same as today there.
  • deploymentId, vary and href stay in the key, so a deploy still busts everything.

Same-shell semantics are unchanged:

  • A stale HTML shell still points at a key whose content hash differs whenever its page changed. That includes index shifts in sections, because the page block's content changes.
  • The server still renders from the current decofile, exactly as today on a miss.

Trade-off: a change to a named block that is referenced from a section's props but isn't on its resolve chain (e.g. a shared loader config) no longer busts that section's render URL. It refreshes through the normal max-age=300 + SWR revalidation, the same freshness HTML pages already have.

Tests

  • hooks/useSection.test.tsx: a new block-content __cb suite, 4 steps:
    • stable when another block is published;
    • changes when a block on the chain changes;
    • changes with the deployment;
    • falls back to the revision.
  • The new steps fail on main (2 of 4) and pass with this change.
  • Full suite: 85 passed, 0 failed.

Not validated yet (why this is a draft)

  • No end-to-end run on a real site. That needs a site pinned to this branch and a check that, after a decofile-only publish, unchanged pages keep their __cb while the edited page's sections get a new one.
  • No production measurement of hit rate after rollout.

Summary by cubic

Keys the lazy-section cache on the content of the blocks on the section's resolve chain instead of the global release revision, so a CMS publish that doesn't change a page no longer invalidates that page's warm CDN entries.

  • The __cb hash now covers the named blocks the section resolves through (e.g. the page), with hashes memoized per block object.
  • Falls back to the release revision when the chain has no named blocks; deploymentId, vary, and href remain in the key.
  • Trade-off: changes to named blocks referenced in props but not on the resolve chain skip the immediate cache bust and refresh via the normal 300s TTL + stale-while-revalidate.
  • Adds tests covering stability across unrelated publishes, invalidation on block or deployment changes, and the revision fallback.

Written for commit 8031a1f. Summary will update on new commits.

View guided diff Turn on auto-fix

… revision

__cb hashed the global release revision, so every CMS publish (a decofile
hot-reload, no deploy) changed the /deco/render URL of every lazy section on
every page and threw away their warm CDN entries. Hash the named blocks on
the section's resolve chain instead (e.g. the page it lives in), memoized
per block object. A publish now only busts lazy sections of the blocks it
changed. Falls back to the revision when the chain has no named block;
deploymentId, vary and href stay in the key.
@coderabbitai

coderabbitai Bot commented Oct 14, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

Tagging Options

Should a new tag be published when this PR is merged?

  • 👍 for Patch 1.213.1 update
  • 🎉 for Minor 1.214.0 update
  • 🚀 for Major 2.0.0 update

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant