The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Shreyash Tripathi raised his portfolio’s reported mobile Lighthouse Performance score from 30 to 80 after prerendering its Vite and React routes and making several other performance changes. The key technique was to generate each known route’s HTML during the build, then hydrate that markup in the browser. The result is a useful implementation case study—not evidence that prerendering alone will produce the same score on another site.
What changed, and what the reported results mean
In a client-rendered React app, the browser may receive a mostly empty root element and need to download and run JavaScript before meaningful page content appears. Tripathi’s build instead rendered HTML for known routes ahead of time. Browsers could display that content before the client code hydrated it.
In his September 26, 2026 case study, Tripathi reported Lighthouse 12 mobile-emulation lab results. He changed more than the rendering strategy, so the before-and-after figures describe the combined work and do not isolate prerendering’s contribution.
Free tools Windows power users keep installed
One-click scans. No signup required.
| Measure | Before | After |
|---|---|---|
| Lighthouse Performance score | 30 | 80 |
| Largest Contentful Paint (LCP) | 8.1 s | 3.4 s |
| Total Blocking Time (TBT) | 3,390 ms | 240 ms |
| Cumulative Layout Shift (CLS) | 0.014 | 0 |
| Words visible without JavaScript | 134 | 1,007 |
These are the author’s reported measurements, not field-user data or an independently replicated test. The increase should not be treated as a promised outcome. Read Tripathi’s case study.
#1 Best Overall
How the Vite prerendering setup worked
The approach created static HTML for routes known at build time, using a server-rendered React tree and a route-specific location. The browser then hydrated the existing markup rather than starting with an empty root.
1. Build both the client and server entries
The build command ran a standard Vite build, an SSR build for src/entry-server.tsx, and a Node prerender script. The server entry rendered the app with React’s renderToString and React Router’s StaticRouter, which lets the rendered tree reflect a particular route without browser navigation.
2. Render each route into the HTML template
The prerender script iterated over the route list, rendered each route, and replaced the root placeholder in the HTML template with that route’s markup. The resulting output provided content in the initial document instead of waiting for client-side rendering to create it.
Recommended Free Tools
Rank #2
3. Hydrate the existing content in the browser
The client entry checked whether the root already contained children. When it did, it called hydrateRoot; otherwise, it used createRoot to render normally. Hydration attaches React’s client behavior to server-generated HTML, so content can appear early while interactive controls still depend on JavaScript.
Vite documents the general client-entry/server-entry pattern and template injection, but describes its low-level SSR API as primarily intended for library and framework authors. Its guide points application developers toward higher-level setups as well; a hand-rolled prerender script is one possible implementation, not the only official route. Vite’s SSR guide explains the structure.
Why prerendering was only part of the optimization
Tripathi also changed how the page’s JavaScript, images, effects, animations, and fonts affected startup and rendering. He summarized the boot-screen problem this way: “It was fun. It was also my LCP.” The remark refers to the autoplay boot screen in his portfolio and appears in his case study.
Rank #3
- Deferred interactive effects: Effects that were not needed for the initial view were postponed rather than competing with startup work.
- Delayed a chart: The chart was loaded when it approached the viewport, instead of being part of the immediate page workload.
- Compressed the profile image: Reducing image weight can help the browser fetch and display visual content sooner.
- Changed animation techniques and reduced expensive blur: The author adjusted animations and toned down blur effects that were costly to render.
- Adjusted font loading: Font-loading behavior was changed as part of the overall work.
The case study does not establish an isolated improvement for each change. Taken together, however, they illustrate why sending initial HTML is not a complete performance strategy: a page can still be slowed by heavy assets, main-thread work, or effects that delay its most important content.
Choose rendering based on how routes and content change
Build-time prerendering, request-time server rendering, and client-side rendering solve different delivery problems. The most useful question is whether a page’s route and content can be determined before deployment, or must be generated for each request.
| Approach | When HTML is generated | Fits best when | Important trade-off |
|---|---|---|---|
| Build-time prerendering or static site generation (SSG) | During the build, for each configured route | Routes and their content are known in advance and do not need per-request personalization | Can deliver ready-made HTML and deploy as static files, but generating every possible URL is difficult for very large or unpredictable route sets. Build setup and maintenance add complexity. |
| Request-time server-side rendering (SSR) | On the server for an incoming request | Responses depend on request-specific data or personalization | Can produce dynamic HTML per request, but server rendering work contributes to response time and requires a runtime server setup. |
| Client-side rendering (CSR) | In the browser after JavaScript runs | The app is primarily interactive and can tolerate content being created on the client | The browser may need to download and execute JavaScript before it can render meaningful content. |
Static output can be served from a CDN, and static rendering can support fast first content paint and time to first byte. But prerendering HTML does not automatically make a page interactive without JavaScript. Hydration still needs scripts to run, and that work can delay interaction. web.dev’s rendering overview discusses these distinctions, while React’s app-from-scratch guidance notes that SSG can improve performance but brings setup and maintenance complexity.
Rank #4
Hydration pitfalls to watch for
Hydration assumes that the server-rendered markup corresponds to the initial tree React builds on the client. If those trees differ, React may be unable to attach behavior cleanly to the existing markup.
Keep the route and shared tree consistent
The server and browser should represent the same route and include compatible shared providers and app structure. In Tripathi’s setup, that meant making sure the provider tree and route tree were represented consistently on both sides.
Understand what Suspense can change
The author reported that a lazy component inside Suspense caused a fallback to client rendering with renderToString. If a route’s server output falls back rather than including the content expected by the client, the initial-render behavior may differ from what you intended. Test routes with lazy components and verify the generated HTML, not only the hydrated page.
React’s static React DOM API reference documents static rendering APIs. The exact rendering behavior depends on the API and app structure, so check the current React documentation before choosing an implementation.
How to evaluate the result on your own app
Use a repeatable measurement process and treat a Lighthouse score as one diagnostic, not a guarantee of how every visitor will experience the site. Compare the same routes under the same test conditions, and note the Lighthouse version, device emulation, and whether the numbers are lab or field data. If you change several things together, report the result as a combined optimization rather than attributing it all to prerendering.
- Check that each intended route produces meaningful HTML in its built output before JavaScript runs.
- Test that hydration works on those routes, including pages with lazy-loaded components and shared providers.
- Measure whether the largest visible content, blocking work, and layout shifts improved after the change.
- Separate rendering changes from asset, animation, effect, and font changes when you need to understand which work helped.
React’s Profiler can help examine rendering within a React tree. React notes that profiling adds overhead and is disabled in production by default, so it is a diagnostic tool—not proof that a particular site will gain a specific Lighthouse score.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

