Skip to content

feat: opt-in static-asset precompression (precompress) - #3452

Draft
nitedani wants to merge 4 commits into
vikejs:mainfrom
nitedani:feat/precompress
Draft

feat: opt-in static-asset precompression (precompress)#3452
nitedani wants to merge 4 commits into
vikejs:mainfrom
nitedani:feat/precompress

Conversation

@nitedani

@nitedani nitedani commented Aug 5, 2026

Copy link
Copy Markdown
Member

Implements the Vike half of #3451, paired with universal-deploy/universal-deploy#35 (and its chain #36/#37). Draft until @universal-deploy/node publishes the precompress option — this PR deliberately omits the packages/vike/package.json range bump, and its typecheck is red against the currently published package (verified green against the linked implementation; it is publication timing, not design).

// pages/+config.ts
export default {
  server: true,
  precompress: true,
} satisfies Config

precompress?: boolean (default false, @experimental): the build emits .br/.gz variants of static assets — including pages pre-rendered during vike build — and the generated server serves them via srvx's encodings lookup with a known Content-Length and no request-path compression. Pages from a separate $ vike prerender run get no variants (no build runs to create them).

Vike's side is a boolean pass-through to universalDeploy({ node: { precompress } }); emission and serving live in @universal-deploy/node (universal-deploy#35 has the full design, including why on-the-fly compression stays enabled for everything else). Docs: a ## Precompression section on /server, covering the prod.static interaction.

Naming: flat +precompress was chosen as the smallest surface. If you'd rather it live under a future namespaced static/cache-policy home, a pre-release rename is cheap — say so.

Verified end-to-end against the linked implementation through the real production path (pnpm run build && node dist/server/index.mjs): variants on disk, content-length == on-disk variant size on the wire, no .br/.gz entries in the client asset manifest, with the remove-the-flag RED control recorded.

nitedani and others added 4 commits August 5, 2026 00:14
Add a Precompression section to the +server docs covering the opt-in
config, its self-host-only scope, and the prod.static interaction that
can silently bypass the emitted variants.

Refs vikejs#3451

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Expose +precompress, forwarded to the Universal Deploy node adapter,
which emits .br/.gz variants at build time and serves them instead of
compressing static assets on every request. Opt-in; default unchanged.
Depends on an unreleased @universal-deploy/node; the dependency range
is bumped separately once it publishes.

Refs vikejs#3451

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Enable precompress in the test app and assert the three-way split the
feature requires: the .br variant exists on disk (emission), the
response carries content-encoding: br (negotiation), and content-length
equals the on-disk variant size (the file was served, not re-encoded).
Also assert no .br/.gz entries reach the client asset manifest, which
preload tags are generated from.

Refs vikejs#3451

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Align the docs with the final adapter behavior: pre-rendering during
`vike build` is covered while a separate `vike prerender` run is not;
`public/` files are copied as-is and their variants stay user-owned;
a `prod.static` override disables the precompressed lookup — the path
has to match exactly, so the same folder spelled a different way
(letter case, a symlink) counts as a different folder — and falls back
to per-request compression; assets that aren't precompressed are still
compressed per request as before. Also normalize the section's heading
spacing.

Refs vikejs#3451

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@brillout

brillout commented Aug 5, 2026

Copy link
Copy Markdown
Member

👍 Let me know when it's ready for review

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.

2 participants