perf(web): prerender the site instead of rendering it per request
apps/web had no request-dependent output — one route, all copy imported
from src/content/*.json at build time, and not a server function or loader
in the app — so every request paid for an SSR invocation that produced
byte-identical HTML.
tanstackStart({ prerender: { enabled: true } }) runs that same server
bundle once at build time and writes dist/client/index.html, which is
already the worker's assets directory. Cloudflare now serves the page from
the asset layer: verified under wrangler dev, GET / returns
CF-Cache-Status: HIT, so the worker never runs. It is still built and
deployed, and still answers what the assets miss — GET /nope returns a
worker-rendered 404 exactly as before.
Also ignore .wrangler/, the local state dir `make web:preview` writes.
This commit is contained in:
@@ -16,6 +16,10 @@ dist/
|
||||
.nitro/
|
||||
.tanstack/
|
||||
|
||||
# Wrangler's local state and scratch dirs, written by `make web:preview`
|
||||
# (wrangler dev). Machine-local simulation of the Cloudflare runtime.
|
||||
.wrangler/
|
||||
|
||||
# Turbo
|
||||
.turbo/
|
||||
|
||||
|
||||
@@ -300,6 +300,18 @@ until the merge. Build logs live in the dashboard, not in the Actions tab.
|
||||
This is why `apps/web/wrangler.jsonc` declares no `env` block — one worker, and the branch
|
||||
decides the command. `make web:deploy` remains as a manual override that authenticates as you.
|
||||
|
||||
**What gets deployed is prerendered, not server-rendered.** `vite.config.ts` passes
|
||||
`prerender: { enabled: true }` to `tanstackStart()`, so the build runs the server bundle once and
|
||||
writes `dist/client/index.html` — which is the worker's assets directory, so Cloudflare serves
|
||||
the page as a static file and the worker is never invoked for a normal view. It is still built
|
||||
and still deployed: it answers whatever the assets do not match, which is what renders the 404.
|
||||
|
||||
That has a consequence worth knowing before you reach for one. **A server function or route
|
||||
loader added to this app will run at build time, not per request** — its result gets baked into
|
||||
the HTML. That is correct for this site, which has one route and imports all of its copy from
|
||||
`src/content/*.json`, but the day the page genuinely needs request-dependent output, turning
|
||||
prerendering off is the change to make, not working around it.
|
||||
|
||||
## Releases
|
||||
|
||||
`@airshiplabs/cli` is the only package published to npm. Everything else in the workspace is
|
||||
|
||||
+14
-1
@@ -11,7 +11,20 @@ import { defineConfig } from "vite";
|
||||
//
|
||||
// Port 5173; airship's overlay always takes TARGET + 1, so `make run` serves the
|
||||
// editor on 5174. See the root Makefile.
|
||||
//
|
||||
// Prerendered, because nothing on this page depends on the request. There is one
|
||||
// route, its copy is imported from content/*.json at build time, and there is not
|
||||
// a server function or loader in the app — so SSR was rendering the same bytes on
|
||||
// every hit. `prerender` runs that same server bundle once at build time and
|
||||
// writes dist/client/index.html, which is already the worker's assets directory:
|
||||
// Cloudflare serves it as a static file and the worker never wakes up for a normal
|
||||
// page view. The worker is still built and still deployed — it is what answers
|
||||
// paths the assets do not match, which is how the 404 keeps rendering.
|
||||
export default defineConfig({
|
||||
plugins: [tailwindcss(), tanstackStart(), react()],
|
||||
plugins: [
|
||||
tailwindcss(),
|
||||
tanstackStart({ prerender: { enabled: true } }),
|
||||
react(),
|
||||
],
|
||||
server: { port: 5173 },
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user