Deliver Faster Pages
Without Rebuilding Your App
Faster load times. Higher engagement. Lower development costs.
React Server Components improve the metrics that drive conversions, SEO, and team velocity.
Faster Pages, Higher Conversions
Your pages load faster because heavy processing happens on the server instead of your users' phones and laptops. Less code to download means faster pages and better Google performance scores.
Real numbers from this demo: Blog 419 KB → 128 KB · Product 801 KB → 397 KB · all 4 demos compared
<%= stream_react_component_with_async_props(
"BlogPostRSC",
props: { title: @post.title }
) do |emit|
# Runs concurrently in background
# while shell streams to browser
# Stream content to React component
emit.call("content", @post.content)
# Stream related posts
emit.call("related", @post.related_posts)
end %>
// 0 KB to browser — server only
import { marked } from 'marked'; // 36 KB
import hljs from 'highlight.js'; // 200+ KB
marked.use({
highlight: (code, lang) =>
hljs.highlight(code, { language: lang }).value
});
export default async function Content(
{ getReactOnRailsAsyncProp: getAsync }
) {
const md = await getAsync('content');
return <article>{marked(md)}</article>;
}
What this means: Your team writes less code, and your users download zero JavaScript for content rendering — the server handles it all. The result is faster pages, better Google performance scores, and lower bandwidth costs.
Users See Content Immediately
Traditional rendering makes users stare at a blank page until everything is ready. RSC shows the page layout immediately and fills in content as it becomes available — users see progress, not emptiness.
export default function ProductPage({ product }) {
return (
<>
<ProductHeader product={product} /> {/* instant */}
<Suspense fallback={<Skeleton />}>
<AsyncReviews /> {/* streams when ready */}
</Suspense>
<Suspense fallback={<Skeleton />}>
<AsyncRecommendations /> {/* streams independently */}
</Suspense>
</>
);
}
Instant Page Layout
Layout, navigation, and structure appear in milliseconds. Users can orient themselves immediately while content-heavy sections load in the background.
Fastest Content First
The most important content renders first. Slower sections stream in independently. Users see real progress, not a frozen screen.
Slow Data Doesn't Block Fast Content
Each page section loads independently. A slow recommendation engine doesn’t block the product details from appearing.
Interactive Elements Work Immediately
Users can tap buttons and fill forms in sections that are already loaded while other content continues streaming in.
Complete Content in Every Page Load
Traditional lazy loading leaves gaps in your initial page — content only appears after JavaScript runs. RSC delivers 100% complete pages on the first load, fully visible to search engines and immediately usable by your customers.
The @loadable/component Tradeoff
You can SSR every loadable component — but the architecture forces a painful choice:
SSR’ing everything delays TTFB and FCP — @loadable’s ChunkExtractor requires renderToString, which cannot stream. The server must finish rendering all components before sending any HTML.
Every SSR’d component still needs JS for hydration — the HTML is visible but frozen until its JavaScript downloads, parses, and executes. More components = more JS = higher TTI.
So teams are forced to choose: SSR critical components for fast FCP (non-critical content missing from HTML), or SSR everything for complete HTML (but slow FCP and heavy hydration).
RSC eliminates this tradeoff. Server components are in the initial HTML AND cost zero JavaScript AND require zero hydration. No penalty for rendering everything on the server.
| Aspect | @loadable/component | React Server Components |
|---|---|---|
| JavaScript sent to users | Full component code in lazy chunks — deferred, not eliminated | Zero for server components — truly eliminated |
| Processing needed in browser | Required for every component, including lazy ones after chunks load | Only for interactive 'use client' components |
| Implementation complexity | 5 packages + webpack plugin + SWC/Babel plugin + ChunkExtractor + loadableReady | Add 'use client' to interactive components. Done. |
| Optimization approach | Manual — wrap each import with loadable() |
Automatic at every client component boundary |
| Search engine visibility | Lazy content absent from initial HTML — depends on Google’s JS rendering queue | All content in initial HTML — indexed on first crawl |
Why This Matters for SEO
Google indexes pages in two waves. The first wave reads raw HTML immediately. The second wave renders JavaScript — but with a median delay of ~10 seconds, up to 18 hours at the 99th percentile.
Content behind lazy-loaded components — reviews, recommendations, comments — is exactly the long-tail keyword-rich content that drives organic search traffic. With @loadable, this content is invisible to the first wave. With RSC, it’s all in the initial HTML.
Faster Development, Lower Engineering Costs
Your developers write dramatically less code — fewer lines means fewer bugs, faster feature delivery, and lower maintenance costs.
'use client';
function Reviews({ productId }) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [err, setErr] = useState(null);
useEffect(() => {
let skip = false;
fetch(`/api/reviews/${productId}`)
.then(r => r.json())
.then(d => !skip && setData(d))
.catch(e => !skip && setErr(e))
.finally(() => setLoading(false));
return () => { skip = true; };
}, [productId]);
if (loading) return <Spinner />;
if (err) return <Error />;
return <ReviewList reviews={data} />;
}
async function Reviews(
{ getReactOnRailsAsyncProp }
) {
const get = getReactOnRailsAsyncProp;
const { reviews } = await get('reviews');
return <ReviewList reviews={reviews} />;
}
// No useState. No useEffect.
// No cleanup. No loading state.
// No error boilerplate.
// No stale closures.
// No dependency arrays.
// No API endpoints.
// Just an async function.
What this means: 20 lines of complex code becomes 5 lines of straightforward code. That translates directly to faster feature delivery, fewer production bugs, and lower ongoing maintenance costs for your engineering team.
Simpler Architecture
Server components access data directly. No REST routes, no GraphQL schemas, no fetch libraries.
No Data Loading Bottlenecks
Data loads in parallel on the server with near-zero latency — no sequential request chains slowing down your pages.
Less Code to Maintain
Server components render once and never re-render. Entire categories of performance optimization code become unnecessary.
Works With Your Rails App
RSC is not Next.js-only. React on Rails Pro is the first framework to bring full React Server Components support to Ruby on Rails.
Keep Your Stack
Controllers, routes, views, authentication — everything stays.
Protect Your Existing Investment
No rewrite to Next.js or any Node framework. Adopt RSC incrementally without disrupting your team.
Works With Your Entire Stack
Devise, Pundit, ActiveRecord, Sidekiq — RSC works alongside every gem and tool your team already relies on.
Full RSC Integration
Streaming SSR, RSC payload embedding, client/server code splitting — all handled for you.
Ready to Deliver Faster Pages?
Faster pages, better SEO, lower engineering costs — without re-platforming your Rails app.