Repository navigation
perf(cloudflare): reduce Worker startup module closure - #3199
Conversation
🦋 Changeset detectedLatest commit: 1772c0a The changes in this PR will be included in the next version bump. This PR includes changesets to release 12 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@emdash-cms/admin
@emdash-cms/auth
@emdash-cms/auth-atproto
@emdash-cms/blocks
@emdash-cms/cloudflare
@emdash-cms/contentful-to-portable-text
emdash
create-emdash
@emdash-cms/gutenberg-to-portable-text
@emdash-cms/plugin-cli
@emdash-cms/plugin-test
@emdash-cms/plugin-types
@emdash-cms/registry-client
@emdash-cms/registry-lexicons
@emdash-cms/registry-loader
@emdash-cms/registry-moderation
@emdash-cms/registry-verification
@emdash-cms/sandbox-workerd
@emdash-cms/x402
@emdash-cms/plugin-ai-moderation
@emdash-cms/plugin-atproto
@emdash-cms/plugin-audit-log
@emdash-cms/plugin-color
@emdash-cms/plugin-embeds
@emdash-cms/plugin-field-kit
@emdash-cms/plugin-forms
@emdash-cms/plugin-webhook-notifier
commit: |
Overlapping PRsThis PR modifies files that are also changed by other open PRs:
This may cause merge conflicts or duplicated work. A maintainer will coordinate. |
|
Tested on our real Worker rather than the starter, since this is the site that motivated the thread. Short version: it works, and it removes the workaround we had been carrying. Details, with the caveat that our own entry was already lazy, so our headline numbers move less than yours and that is expected. What we are
The measurement that mattersBecause our entry was already lazy, the honest test is what a static import costs, which is what an ordinary site does and what we had to stop doing:
Same entry, same build, only the packages differ. That is the whole of our workaround made unnecessary — one extra module and 0.02 MB over our hand-lazied build. We can delete the injection hack and go back to a plain static import. With our existing lazy entry, before and after are unchanged, as expected: 21 modules / 1.48 MB → 21 / 1.50 MB, startup active CPU median 29.5 ms → 31.0 ms over nine runs each (min 26.6/27.6, max 34.3/52.4). No regression, no gain, because we were already at the floor. Wrangler 4.x, The Two things you may want to know1. 2. CaveatsOur four remaining local patches could not be applied to the preview build, because they target content-hashed dist filenames ( Tested on our staging environment, not production. The CI guard is the part I would have asked for if you had not included it. The regression we hit was invisible precisely because nothing failed — the build passed, the deploy passed, every page served, and the only symptom was cold pages taking 1–3 seconds. A threshold that fails the build is what stops that recurring. Happy to re-run any of this, or to test again once it is on a release we can install normally. |
|
Thanks for checking. I'll merge this and it'll be in the next release |
What does this PR do?
Reduces the module graph evaluated when an EmDash Cloudflare Worker starts. The Worker entry exports
PluginBridgedirectly, loads scheduled maintenance only when a Cron Trigger runs, and loads the bridge's repository runtime on the first sandbox RPC through a narrowemdash/plugins/hostentry. Existingemdashand@emdash-cms/cloudflare/workerexports remain compatible.Adds a production-build guard that walks static imports from the generated Worker entry. CI now rejects more than 30 eager modules, more than 2 MB of eager JavaScript, or eager WXR, Tiptap/ProseMirror, plugin-registry, and media-maintenance sources.
The query-count harness now disables Astro 7.3's separate dev and preview background modes so local agent runs capture the same query events as CI.
Discussion: #3143
Measured on the production-built Cloudflare starter with Wrangler 4.125.0, using one discarded warm-up and nine startup samples:
The narrow bridge runtime adds 928 KB on the first sandbox RPC, keeping startup plus first plugin use at approximately 2.66 MB instead of loading the 5.72 MB root barrel. Testing Cloudflare's
new_module_registryflag increased the optimized median to 35.4 ms, so this PR does not enable it.Type of change
Checklist
pnpm typecheckpassespnpm lintpassespnpm testpasses (or targeted tests for my change)pnpm formathas been runmessages.pochanges except in translation PRs — a workflow extracts catalogs on merge tomain.The localization, new-feature, and screenshot items are not applicable: this changes Worker startup timing without adding admin UI or a new product capability.
AI-generated code disclosure
Screenshots / test output
Not applicable — no UI changes.
Validated on the exact merged
origin/mainhead with:pnpm install --frozen-lockfilepnpm buildpnpm typecheckpnpm lintpnpm format:checkpnpm --dir packages/cloudflare test— 436 passedpnpm query-counts --target d1— count and SQL snapshots matchpnpm --dir templates/starter-cloudflare buildpnpm startup:check— 18 modules, 1,734,286 byteswrangler check startup— 19.0 ms median across nine measured runsThe package API linter (
publint) passes for both changed packages. The secondaryattw --packprocess crashes after packing withCannot read properties of undefined (reading 'filename')for both packages and does not report a package diagnostic.