Astro Info
Astro v7.3.1
Node v22.22.2
System Linux (x64)
Package Manager pnpm
Output server
Adapter @astrojs/cloudflare
Integrations none
If this issue only occurs in one browser, which browser is a problem?
No response
Describe the Bug
Since 7.2.1, middleware invalidations no longer filter out unrelated hotUpdate triggers, causing extra invalidations, extra SSR, extra load times.
PR #17605, which fixed #17590, replaced server.watcher.on("change", ...) with a hotUpdate handler that takes no arguments and invalidates middleware without regard for the nature of the update. The old code had some quick checks and early returns:
// v 7.2.0
server.watcher.on("change", (path) => {
const normalizedPath = viteNormalizePath(path);
if (!normalizedPath.startsWith(normalizedSrcDir)) return; // not under srcDir
const relativePath = normalizedPath.slice(normalizedSrcDir.length);
if (!isMiddlewarePath(relativePath)) return; // not the middleware
// ...invalidate
});
You can see the "if (x) early return" happening twice. The new code takes no arguments so the handler is unable to inspect the change for relevance:
// v 7.2.1 and later
hotUpdate: {
handler() {
if (!isAstroServerEnvironment(this.environment)) return;
const middlewareVirtualMod = this.environment.moduleGraph
.getModuleById(MIDDLEWARE_RESOLVED_MODULE_ID);
if (!middlewareVirtualMod) return;
this.environment.moduleGraph.invalidateModule(middlewareVirtualMod);
this.environment.hot.send("astro:middleware-updated", {});
}
}
A partial fix for some of the more provably useless updates is to check for an empty ctx.modules array, and return early. That fix also resolves #17922, and may improve the situation for some other recent bug-filings involving cloudflare/workerd, middleware and SSR over-rebuilding.
I suspect this is starting to bite more often because of changes to the @cloudflare/vite-plugin, which by default now writes to .wrangler/state on every pageload (writing the trace to SQLite), which Vite's watcher sees as a file change, firing the hotUpdate hook every time any of Miniflare's different services write to their local state. (That is filed as cloudflare/workers-sdk#15550 -- careful, it only reproduces on Windows or Linux, in case you get curious.) On a fresh, new EmDash site, the combination of this Miniflare-state-mutation -> Vite hotUpdate -> Astro middleware rebuild -> SSR rebuild, means that simply loading localhost:4321 was taking 30 second on my Linux machine.
On @astrojs/node the invalidation fires too — it's just rare and cheap (12 handler calls, 6 invalidations for three file touches; requests stay at 0.03s). On @astrojs/cloudflare, five plain requests with nothing edited produced 222 handler calls and 111 invalidations — about 22 invalidations per request, because Miniflare rewrites its trace-store SQLite repeatedly while serving a single page. Only one or two distinct files change per request, out of 21 in the directory — it's the same file being written over and over, and every write fires the hook.
What's the expected result?
hotUpdate events that list no changed modules should be discarded rather than invalidating middleware.
draft fix: https://github.com/mhsnook/astro/pull/1/changes
Link to Minimal Reproducible Example
https://github.com/mhsnook/bug-repro-astro-hmr
Participation
Astro Info
If this issue only occurs in one browser, which browser is a problem?
No response
Describe the Bug
Since 7.2.1, middleware invalidations no longer filter out unrelated hotUpdate triggers, causing extra invalidations, extra SSR, extra load times.
PR #17605, which fixed #17590, replaced
server.watcher.on("change", ...)with a hotUpdate handler that takes no arguments and invalidates middleware without regard for the nature of the update. The old code had some quick checks and early returns:You can see the "if (x) early return" happening twice. The new code takes no arguments so the handler is unable to inspect the change for relevance:
A partial fix for some of the more provably useless updates is to check for an empty
ctx.modulesarray, and return early. That fix also resolves #17922, and may improve the situation for some other recent bug-filings involving cloudflare/workerd, middleware and SSR over-rebuilding.I suspect this is starting to bite more often because of changes to the
@cloudflare/vite-plugin, which by default now writes to.wrangler/stateon every pageload (writing the trace to SQLite), which Vite's watcher sees as a file change, firing the hotUpdate hook every time any of Miniflare's different services write to their local state. (That is filed as cloudflare/workers-sdk#15550 -- careful, it only reproduces on Windows or Linux, in case you get curious.) On a fresh, new EmDash site, the combination of this Miniflare-state-mutation -> Vite hotUpdate -> Astro middleware rebuild -> SSR rebuild, means that simply loading localhost:4321 was taking 30 second on my Linux machine.On
@astrojs/nodethe invalidation fires too — it's just rare and cheap (12 handler calls, 6 invalidations for three file touches; requests stay at 0.03s). On@astrojs/cloudflare, five plain requests with nothing edited produced 222 handler calls and 111 invalidations — about 22 invalidations per request, because Miniflare rewrites its trace-store SQLite repeatedly while serving a single page. Only one or two distinct files change per request, out of 21 in the directory — it's the same file being written over and over, and every write fires the hook.What's the expected result?
hotUpdate events that list no changed modules should be discarded rather than invalidating middleware.
draft fix: https://github.com/mhsnook/astro/pull/1/changes
Link to Minimal Reproducible Example
https://github.com/mhsnook/bug-repro-astro-hmr
Participation