Overview
Poke-Nex leverages Static Site Generation (SSG) combined with Incremental Static Regeneration (ISR) to deliver instant page loads and SEO-ready content while keeping data fresh. The application pre-renders 1025+ Pokémon pages at build time, achieving exceptional performance metrics.Build Performance: 1030+ static pages generated in < 12 seconds using multi-threaded worker pools.
Static Site Generation (SSG)
Pre-rendering All Pokémon Pages
Every Pokémon detail page is statically generated at build time using thegenerateStaticParams function. This ensures instant page loads with zero API calls at runtime.
src/app/pokemon/[slug]/page.tsx
- At build time,
generateStaticParamsfetches the complete list of 1025+ Pokémon - Next.js generates a static HTML page for each Pokémon slug
- All pages are deployed as pre-rendered HTML files
- Users get instant page loads with full SEO metadata
Dynamic Metadata Generation
Each static page includes dynamically generated metadata for optimal SEO:Incremental Static Regeneration (ISR)
Revalidation Strategy
Poke-Nex implements a weekly ISR cycle (604,800 seconds) to keep data fresh without sacrificing performance:src/lib/api/pokemon.api.ts
- Pokemon detail pages: 604,800 seconds (7 days)
- Pokemon list (GraphQL): 604,800 seconds (7 days)
- Variety data: 604,800 seconds (7 days)
How ISR Works in Poke-Nex
- Initial Build: All 1030+ pages are generated statically
- Serving Static Pages: Users receive instant HTML responses from the CDN
- Background Revalidation: After 7 days, the next request triggers background regeneration
- Stale-While-Revalidate: Users continue seeing the cached version while the page regenerates
- Updated Cache: New requests receive the freshly regenerated page
Service Layer Architecture
Clean Architecture Pattern
Poke-Nex implements a clean architecture with separate layers for API calls, data adaptation, and business logic:src/services/pokemon.service.ts
- Fetchers (
pokemon.api.ts): Raw API calls with ISR configuration - Adapters (
pokemon-detail.adapter.ts): Transform API responses to application models - Services (
pokemon.service.ts): Business logic and error handling - Pages: Consume services for rendering
GraphQL for Optimized List Fetching
The home page uses GraphQL to fetch only the necessary fields for the Pokémon list:src/lib/api/pokemon.api.ts
GraphQL fetching reduces payload size by requesting only
id, name, and types for list views, improving build time and initial page load.Performance Metrics
Build Time Performance
- Total Pages: 1030+ (1025 Pokémon + app pages)
- Build Time: < 12 seconds
- Parallel Processing: Multi-threaded worker pools
- Average Time per Page: ~0.011 seconds
Runtime Performance
- LCP (Largest Contentful Paint): Instant (pre-rendered HTML)
- TTI (Time to Interactive): < 1 second
- API Calls at Runtime: 0 (fully static)
- CDN Cache Hit Rate: ~100%
Best Practices
1. Use Extended Fetch Selectively
Theextended parameter in fetchPokemonByID controls whether to fetch additional data:
2. Configure Appropriate Revalidation Periods
- Static data (Pokémon stats): 7 days or more
- User-generated content: 1 hour or less
- Frequently updated data: Consider on-demand revalidation
3. Error Handling for Build Failures
Always handle errors gracefully to prevent build failures:4. Implement Proper SEO Metadata
Generate unique metadata for each static page:- Title: Include Pokémon name and site name
- Description: Concise summary of page content
- Open Graph: Include high-quality images
- JSON-LD: Structured data for search engines
Related Documentation
- Performance Optimizations - Learn about additional performance techniques
- Hydration Strategy - Understand client-side hydration for persisted state