SSR vs CSR
Définition
SSR (Server-Side Rendering) génère le HTML complet sur le serveur, facilitant l'indexation SEO et le scraping. CSR (Client-Side Rendering) génère le contenu via JavaScript dans le navigateur, nécessitant un headless browser pour le scraping. Les frameworks modernes (Next.js, Nuxt) combinent les deux approches.
Deep Dive
SSR vs CSR : impact sur le crawling et le SEO
Comparatif technique
| Aspect | SSR | CSR |
|--------|-----|-----|
| HTML initial | Complet | Minimal (shell) |
| Temps au contenu | Rapide | Après JS load |
| SEO / Crawling | Excellent | Problématique |
| Interactivité | Après hydration | Immédiate |
| Charge serveur | Plus élevée | Minimale |
Évolution des architectures
**Génération 1 : PHP/Rails (Pure SSR)**
**Génération 2 : React SPA (Pure CSR)**
**Génération 3 : Next.js/Nuxt (Hybride)**
Détection du mode de rendu
Pour savoir si un site utilise CSR :
1. Désactiver JavaScript dans le navigateur
2. Si la page est vide → CSR pur
3. Si le contenu apparaît → SSR ou SSG
Code Playground
Détection automatique du mode de rendu et sélection de la stratégie de scraping optimale
# Détection automatique SSR vs CSR et stratégie de scraping adaptée
import httpx
from playwright.async_api import async_playwright
from selectolax.parser import HTMLParser
async def detect_rendering_mode(url: str) -> dict:
"""Détecte si un site utilise SSR ou CSR"""
# 1. Fetch HTML brut (sans JavaScript)
async with httpx.AsyncClient() as client:
response = await client.get(url)
raw_html = response.text
raw_tree = HTMLParser(raw_html)
raw_text_content = raw_tree.body.text(strip=True) if raw_tree.body else ""
# 2. Fetch avec JavaScript (Playwright)
async with async_playwright() as p:
browser = await p.chromium.launch()
page = await browser.new_page()
await page.goto(url, wait_until='networkidle')
rendered_html = await page.content()
await browser.close()
rendered_tree = HTMLParser(rendered_html)
rendered_text_content = rendered_tree.body.text(strip=True) if rendered_tree.body else ""
# 3. Comparer les contenus
raw_length = len(raw_text_content)
rendered_length = len(rendered_text_content)
content_ratio = raw_length / rendered_length if rendered_length > 0 else 0
# Heuristique : si le HTML brut contient moins de 30% du contenu rendu
is_csr = content_ratio < 0.3
return {
'url': url,
'mode': 'CSR' if is_csr else 'SSR',
'raw_content_length': raw_length,
'rendered_content_length': rendered_length,
'content_ratio': round(content_ratio, 2),
'recommendation': 'Use headless browser' if is_csr else 'Simple HTTP fetch is sufficient'
}
async def adaptive_scrape(url: str):
"""Scrape adaptatif selon le mode de rendu détecté"""
mode_info = await detect_rendering_mode(url)
if mode_info['mode'] == 'SSR':
# Scraping simple et rapide
async with httpx.AsyncClient() as client:
response = await client.get(url)
return HTMLParser(response.text)
else:
# Scraping avec JavaScript rendering
async with async_playwright() as p:
browser = await p.chromium.launch()
page = await browser.new_page()
await page.goto(url, wait_until='networkidle')
html = await page.content()
await browser.close()
return HTMLParser(html)Avis d'Expert 2026
La tendance 2026 est au "Partial Hydration" et aux "Server Components" (React) qui complexifient encore la donne. Les scrapers professionnels maintiennent des profils par domaine indiquant le mode de rendu optimal. L'idéal reste de détecter automatiquement et d'utiliser la méthode la plus légère possible.
Besoin d'aide sur SSR vs CSR ?
Nos experts peuvent vous accompagner sur vos projets de crawling et d'optimisation GEO.
Contactez l'expert Crawlers.fr