Skip to content

perf: skip user lookup on SPA shell route#2461

Merged
aalemayhu merged 1 commit into
mainfrom
perf/skip-user-lookup-on-shell-route
May 19, 2026
Merged

perf: skip user lookup on SPA shell route#2461
aalemayhu merged 1 commit into
mainfrom
perf/skip-user-lookup-on-shell-route

Conversation

@aalemayhu
Copy link
Copy Markdown
Contributor

@aalemayhu aalemayhu commented May 19, 2026

Summary

GET / and every non-/api route serve a static React shell — sendIndex reads index.html from disk and writes it back unchanged. It never reads res.locals.

The previous handler ran configureUserLocal first, which does up to 4 sequential database queries (user-by-token, isSubscriber, findActive pass, subscriptionInfo) on every page load. The SPA fetches user state via /api/users/debug/locals after hydration anyway, so the work was wasted.

This drops the call from the shell route only — RequireAuthentication, RequirePaying, and RequireAllowedOrigin middlewares still use configureUserLocal for API routes that genuinely need user identity.

Why this is also a bug fix

The previous code was:

configureUserLocal(...).then(() => { sendIndex(response); });

No .catch. When configureUserLocal threw — e.g. TokenExpiredError on a stale cookie, visible in prod logs right now — the response was never sent. The request just hung until the client timed out.

Test plan

  • pnpm test src/controllers/IndexController — 10 tests pass
  • pnpm tsc --noEmit clean
  • After deploy, curl https://2anki.net/ and confirm TTFB drops (was ~150ms server-side; expect <50ms)

🤖 Generated with Claude Code


View in Codesmith
Need help on this PR? Tag @codesmith with what you need.

  • Let Codesmith autofix CI failures and bot reviews

GET / and other non-/api routes serve a static React shell — sendIndex
reads index.html from disk and writes it back unchanged. It never reads
res.locals.

The previous handler ran configureUserLocal first, which does up to 4
sequential database queries (user-by-token, isSubscriber, findActive
pass, subscriptionInfo). The SPA fetches all that via
/api/users/debug/locals after hydration anyway.

Dropping the call removes the queries from the shell route and fixes a
latent bug: configureUserLocal was chained via .then() without a .catch,
so a thrown TokenExpiredError (visible in prod logs) silently never
sent a response.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@aalemayhu aalemayhu merged commit 5553503 into main May 19, 2026
4 checks passed
@aalemayhu aalemayhu deleted the perf/skip-user-lookup-on-shell-route branch May 19, 2026 16:17
@netlify
Copy link
Copy Markdown

netlify Bot commented May 19, 2026

Deploy Preview for notion2anki ready!

Name Link
🔨 Latest commit aa244ef
🔍 Latest deploy log https://app.netlify.com/projects/notion2anki/deploys/6a0c8d321b21e70008713fbd
😎 Deploy Preview https://deploy-preview-2461--notion2anki.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@sonarqubecloud
Copy link
Copy Markdown

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.

1 participant