Advanced Server-Side Rendering and SSG with Spring Boot & React
Your previous blog post covering SSR with Spring Boot and React gained a lot of attention. This follow-up goes deeper—covering advanced techniques like Static Site Generation (SSG), React hydration strategies, CDN optimization, and DevOps deployment flows.
1. SSR vs. SSG: What's the Difference?
SSR (Server-Side Rendering) means rendering React components on the server at runtime. SSG (Static Site Generation) pre-renders pages at build time. Both help with:
- SEO improvement (bots get HTML)
- Faster first paint (TTFB optimized)
- Better perceived performance
SSG is best for static content. SSR is ideal when data must be fetched at request time.
2. Review: SSR with Spring Boot + Thymeleaf
Your original article explained how to use Thymeleaf for SSR inside a Spring Boot controller:
// Controller
@GetMapping("/")
public String index(Model model) {
model.addAttribute("data", myService.getData());
return "index"; // loads index.html
}
This works well, but mixing server and React logic can become inflexible. Let’s explore alternatives.
3. Option A: Full SSR using Express + React + Spring API
Let Spring Boot serve the API, and let an Express server render the React app on the server:
3.1 Express SSR Setup
// server.js
import express from 'express';
import React from 'react';
import { renderToString } from 'react-dom/server';
import App from './App';
import fs from 'fs';
import path from 'path';
const app = express();
app.use(express.static('build'));
app.get('*', (req, res) => {
const appHtml = renderToString(<App />);
const indexHtml = fs.readFileSync(path.resolve('./build/index.html'), 'utf8');
const finalHtml = indexHtml.replace('<div id="root"></div>', `<div id="root">${appHtml}</div>`);
res.send(finalHtml);
});
app.listen(3000);
3.2 Benefits
- Decouples rendering from Java stack
- Allows fine-grained control over React hydration
- Frontend stays pure React
4. Option B: Static Site Generation (SSG)
Use tools like react-snap
or vite-plugin-ssg
to prerender your pages at build time.
npx react-snap
// Or with Vite
npm i vite-plugin-ssg
Generated HTML pages can be served by Spring Boot from /static
folder or any CDN.
5. React Hydration Strategies
Hydration reactivates the React app on the client after SSR. To optimize this:
- Use
react-lazy-hydration
orreact-hydrate-on-visiblity
- Split large components using
React.lazy()
andSuspense
- Only hydrate visible sections ("Islands architecture")
import { lazyHydrate } from 'react-lazy-hydration';
lazyHydrate(() => import('./HeavyComponent'), { whenVisible: true });
6. Caching and CDN Strategy
- Use Spring’s
WebMvcConfigurer
to add caching headers - Host static HTML/JS on Cloudflare or AWS CloudFront
@Configuration
public class CacheConfig implements WebMvcConfigurer {
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/")
.setCachePeriod(31556926); // 1 year
}
}
7. SEO Improvements
- Inject
meta
tags server-side usingreact-helmet
- Add Open Graph tags, Twitter cards, and JSON-LD
8. Docker and CI/CD Deployment
Create a multi-stage Dockerfile that builds both Java and Node apps:
# Dockerfile
FROM node:18 as frontend
WORKDIR /app
COPY client/ .
RUN npm install && npm run build
FROM maven:3.8-jdk-17 as backend
WORKDIR /app
COPY server/ .
RUN mvn clean package
FROM openjdk:17
WORKDIR /app
COPY --from=frontend /app/build /app/static
COPY --from=backend /app/target/*.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
9. SSR vs SSG: Decision Matrix
Criteria | SSR | SSG |
---|---|---|
Performance (First Load) | ⚠️ slower | ✅ fast |
SEO | ✅ good | ✅ good |
Dynamic Data | ✅ ideal | ⚠️ limited |
Scalability | ⚠️ costly | ✅ cacheable |
Dev Complexity | ⚠️ high | ✅ simple |
10. Summary
Now you know how to:
- Enhance SSR with Express or use SSG for performance
- Optimize hydration, caching, and SEO
- Deploy the app using Docker and CI/CD
Whether you're building a blog, dashboard, or a public portal, these tools give you full control over rendering and performance.
Next: We’ll explore authentication, role-based views, and SSR-secured routes in Spring + React!
Add your comment