Skip to content

Conversation

ronjalh
Copy link
Member

@ronjalh ronjalh commented Nov 10, 2026

What

Splits the JavaScript per route, from the peer feedback (#167).

  • src/App.tsx: every page except the Elements page is loaded with React.lazy, inside one Suspense with a visible, announced "Loading the page" fallback.
  • The first file goes from 766.83 kB (242.32 kB gzip) to 522.21 kB (166.39 kB gzip). The Gymnast page (31.8 kB), the element page (18.2 kB), the login and the rest load when their route is opened.
  • The five App tests that expected a page at once now wait for it.
  • The numbers in the README and docs/SUSTAINABILITY.md are updated (they said 548 kB), and there is a short entry in docs/AI_USAGE.md.

Why the Elements page is not lazy

/ and the logo lead to it, so nearly every visit needs it. A first version made it lazy too, and App.flow.test.tsx caught a real problem: logging out on the Gymnasts page navigates to /elements; while that file downloaded, the protected page was still mounted and sent the visitor to /login.

Checked

tsc, ESLint and Prettier are clean; the 426 frontend tests and all 57 end-to-end tests pass; npm run build gives the numbers above. The first file is still a little over Vite's 500 kB warning, because the libraries are most of it. The gain on a real connection is measured in #157.

Closes #176

🤖 Generated with Claude Code

Load every page except the Elements page with React.lazy, so the first file
goes from 766.83 kB (242 kB gzip) to 522.21 kB (166 kB gzip). The Elements
page stays in the first file: logging out navigates to it while a protected
page is on the screen. The App tests wait for the lazy pages.

Closes #176
@ronjalh ronjalh requested a review from a team as a code owner November 10, 2026 19:44
@ronjalh ronjalh self-assigned this Nov 10, 2026
Base automatically changed from dev to main November 10, 2026 19:45
@ronjalh ronjalh changed the base branch from main to dev November 10, 2026 19:49
@anettkva
Copy link
Member

anettkva commented Nov 11, 2026 •

Nice and focused change: the numbers match when I build it (522.21 kB / 166.39 kB gzip), and the reason for keeping the Elements page in the first file is clear and well tested.

One thing I'd fix before merging: now that each page is its own file, a failed download of that file (for example after a new deploy on the VM, while someone still has the old version open) throws inside React.lazy, and since there is no error boundary the whole app goes blank. A small error boundary around the Suspense with a "Reload the page" button, or a vite:preloadError listener that reloads, would cover it.

One small note, not blocking:

  • In the "Go to the top" test, await screen.findByRole('main') finds the old page's <main> right away, so it does not wait for the new page.

Generated with Claude Code.

Sign in to join this conversation on GitHub.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants