fix: add @fastify/compress to reduce bundle transfer size on mobile#158
fix: add @fastify/compress to reduce bundle transfer size on mobile#158eusip wants to merge 1 commit intohappier-dev:devfrom
Conversation
The server was serving the web UI JS bundle (~19MB) uncompressed. On mobile networks this caused connections to drop mid-transfer, resulting in the iOS app showing "Server not supported — unexpected response". Registers @fastify/compress globally so all responses (including the static JS bundle) are compressed with gzip/zstd. This fixes the issue at the server layer for all self-hosted deployments, regardless of whether they use Caddy, nginx, or any other proxy.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (2)
WalkthroughThe changes add HTTP compression support to the Fastify server by introducing the Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Greptile SummaryRegisters Confidence Score: 5/5Safe to merge — the change is minimal, correct, and all remaining feedback is a non-blocking performance suggestion Only a P2 observation about per-request re-compression overhead remains; no correctness, security, or reliability issues were found No files require special attention
|
| Filename | Overview |
|---|---|
| apps/server/sources/app/api/api.ts | Registers @fastify/compress globally after cors and rate-limit; plugin is correctly placed before route registration so all responses will be compressed |
| apps/server/package.json | Adds @fastify/compress@8.3.1 (exact-pinned, consistent with @fastify/swagger and @sentry/node); also reorders @sentry/node and @socket.io/redis-streams-adapter alphabetically |
| yarn.lock | Adds lock entries for @fastify/compress and its transitive deps (peek-stream, pumpify, duplexify, through2, stream-shift); lock changes look consistent with the declared dependency |
Sequence Diagram
sequenceDiagram
participant Client as iOS / Mobile Client
participant Fastify as Fastify Server
participant Compress as @fastify/compress
participant StaticHandler as enableServeUi
Client->>Fastify: GET / (Accept-Encoding: gzip)
Fastify->>Compress: onSend hook (check Accept-Encoding)
Fastify->>StaticHandler: route handler
StaticHandler->>StaticHandler: readFile(index.html / bundle.js)
StaticHandler-->>Fastify: reply.send(Buffer ~19MB)
Fastify->>Compress: compress buffer (gzip)
Compress-->>Fastify: compressed payload ~4-5MB
Fastify-->>Client: 200 OK (Content-Encoding: gzip, ~4-5MB)
Client->>Fastify: GET /v1/auth (Accept-Encoding: gzip)
Fastify->>Compress: onSend hook
Fastify-->>Client: 200 OK (Content-Encoding: gzip, small JSON)
Comments Outside Diff (1)
-
apps/server/sources/app/api/utils/enableServeUi.ts, line 30-83 (link)Per-request re-compression of large static assets
readFileloads the entire file into aBufferand then@fastify/compresscompresses it in-process on every request. For the ~19 MB JS bundle this means ~19 MB allocated for the raw content plus another pass to produce the compressed output on every cold fetch — with no caching of the compressed result.This works correctly and solves the mobile drop, but it adds CPU pressure proportional to concurrent downloads. A lower-cost alternative is to pre-compress the bundle at build time (emitting
.gz/.brsiblings) and serve the pre-compressed file directly, or to cache the compressedBufferkeyed by file path after the first compression. Not required to merge, but worth a follow-up ticket if the server serves the bundle to many concurrent mobile clients.
Reviews (1): Last reviewed commit: "fix: add @fastify/compress to reduce bun..." | Re-trigger Greptile
Problem
The Happier server serves the web UI JS bundle (~19MB) without any compression. On mobile networks this causes the TCP connection to drop mid-transfer. The iOS app surfaces this as:
Fix
Register
@fastify/compressglobally instartApi()so all HTTP responses are compressed (gzip/zstd) before transmission. This reduces the ~19MB bundle to ~4–5MB on the wire.The plugin is registered alongside the existing
@fastify/corsand@fastify/rate-limitplugins inapps/server/sources/app/api/api.ts, which is the single entry point for bothfullandlightserver flavors.Impact
Verification
Summary by CodeRabbit