From bd58839d7957b6e3625caf511d35d108a1bde7f1 Mon Sep 17 00:00:00 2001
From: Krish Agarwal
Date: Sat, 31 Oct 2026 17:35:35 +0530
Subject: [PATCH 1/3] Poll the seat counter only while the register form is
open
The register/log-in overlay is mounted, closed, at idle on every home page visit, and its seat counter then polled
GET /api/seats every 30 s for as long as the tab stayed visible: about 2 Vercel edge requests a minute per open tab,
from visitors who never opened the form. Measured on production: 7 calls in under 4 minutes of idling on /.
The counter now mounts when the overlay opens (immediate fetch, then the same 30 s polling) and unmounts after it
closes. The seat check when DETAILS moves on to PAYMENT (authSubmit -> fetchSeatCount) and /api/seats itself are
unchanged.
Co-Authored-By: Claude Opus 5.5
---
src/components/innovision/Innovision.tsx | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/components/innovision/Innovision.tsx b/src/components/innovision/Innovision.tsx
index a1a7c6c..6c8c6b6 100644
--- a/src/components/innovision/Innovision.tsx
+++ b/src/components/innovision/Innovision.tsx
@@ -2947,8 +2947,10 @@ export class Innovision extends Component {
authSub: reg
? 'Three short stops to register for Innovision 2026 at NIT Rourkela.'
: am === 'login' ? 'Sign in or create your account with Google.' : P.status === 'CONFIRMED' ? 'Your payment is verified. Your INNO pass is always available here.' : P.status === 'REJECTED' ? (this.canRegisterAgain() ? 'See why below, then register again with the right details.' : 'Please contact the registration helpdesk for assistance.') : 'Your payment is under review by the registration team. Your pass appears here after approval.',
- // The seat counter (GET /api/seats) beside the registration form.
- showSeats: reg,
+ // The seat counter (GET /api/seats) beside the registration form. Only while the overlay is open: it is mounted,
+ // closed, at idle (warmDeferred), and a mounted counter polls every 30 s. `auth` turns true before the overlay
+ // animates in and false after it has animated out, so the counter is never cut off mid-animation.
+ showSeats: reg && s.auth,
// REGISTER AGAIN on a rejected pass; the pass itself decides whether to show it (attempts left).
registerAgain: REGISTRATIONS_OPEN ? this.registerAgain : undefined,
idCardUploaded: this.idCardUploaded,
From 237c602820245e0be1d1a78d972ac0c360485fc3 Mon Sep 17 00:00:00 2001
From: Krish Agarwal
Date: Sat, 31 Oct 2026 17:38:26 +0530
Subject: [PATCH 2/3] Stop prefetching /merch on every home page view
warmDeferred called router.prefetch for OWN_PAGES (/merch while registrations are open) at idle on every visit.
Next.js 16 splits that into 3 RSC requests (max-age=0, so never browser-cached): 3 Vercel edge requests per home
page view, first or repeat, plus the merch page chunk. MERCH links still switch client-side through the existing
document click listener; the route is fetched on click instead.
Co-Authored-By: Claude Opus 5.5
---
src/components/innovision/Innovision.tsx | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/components/innovision/Innovision.tsx b/src/components/innovision/Innovision.tsx
index 6c8c6b6..f7bc65e 100644
--- a/src/components/innovision/Innovision.tsx
+++ b/src/components/innovision/Innovision.tsx
@@ -728,8 +728,10 @@ export class Innovision extends Component {
this._warmed = true;
if (slowNet()) return;
// The overlay and view a visitor is most likely to open next are fetched ahead too (their own hover/tap also does).
- // The pages of their own too, so MERCH (and REGISTER while closed) open at once (a no-op on the dev server).
- this.cleanups.push(this.idle(() => { this.prefetch('auth'); this.prefetch('detail'); OWN_PAGES.forEach((p) => this.props.router?.prefetch(p)); }));
+ // The pages of their own (OWN_PAGES: MERCH, REGISTER while closed) are NOT prefetched: each router.prefetch cost 3
+ // uncached RSC requests on every home page view, for a page few visitors open. A click on one still switches
+ // client-side (the document click listener in componentDidMount), fetching the route then.
+ this.cleanups.push(this.idle(() => { this.prefetch('auth'); this.prefetch('detail'); }));
// The menu (where the top bar has a MENU button) and the register / log-in overlay are mounted, closed, ahead of
// time: mounting one on its first tap blocked a phone for ~100 ms just as its reveal began. One per idle period.
this.cleanups.push(this.idle(() => {
From b801cc8058d2cb86aadf2c16eccb8535dfefba8f Mon Sep 17 00:00:00 2001
From: Krish Agarwal
Date: Sat, 31 Oct 2026 17:39:16 +0530
Subject: [PATCH 3/3] Turn off viewport prefetching for events page links
Every on /events, /events/ and in EventsChrome (also the frame of /privacy and /terms) was prefetched
as it entered the viewport: 3 to 5 RSC requests per page view on production, none browser-cached. With
prefetch={false} the links still navigate client-side and fetch the route on click.
Co-Authored-By: Claude Opus 5.5
---
src/app/events/[world]/page.tsx | 4 ++--
src/app/events/page.tsx | 6 +++---
src/components/events/EventsChrome.tsx | 20 +++++++++++---------
3 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/src/app/events/[world]/page.tsx b/src/app/events/[world]/page.tsx
index ba62e12..d73f78c 100644
--- a/src/app/events/[world]/page.tsx
+++ b/src/app/events/[world]/page.tsx
@@ -95,7 +95,7 @@ export default async function WorldPage({ params }: PageProps<'/events/[world]'>