Les pages de documentation ne ratent pas parce que l’API est déroutante. Elles ratent parce que la page elle‑même épuise le lecteur : mise en page instable, navigation qui perd, et contenu qui se lit comme s’il avait été versé depuis un PDF. Les utilisateurs ne « quittent pas en colère ». Ils repartent simplement en silence, et votre file de support prend de l’ampleur.
J’ai vu des équipes passer des mois à polir le texte alors que leur frontend livrait une mise en page lente et instable qui rendait la lecture comparable au débogage sur le Wi‑Fi d’un hôtel. La solution n’est pas un nouveau thème. C’est un modèle de page reproductible qui respecte l’attention, les budgets de performance et la façon dont les gens parcourent réellement le contenu.
Le modèle : une page de docs qui se comporte
La mise en page gagnante pour la documentation est ennuyeuse dans le bon sens : elle est prévisible, rapide et n’oblige pas le lecteur à se réorienter toutes les 20 secondes. Voici le modèle qui maintient systématiquement les gens en train de défiler.
Structure recommandée (bureau)
- En‑tête : fin, hauteur stable, pas de « bandeau d’annonce » qui pousse toute la page vers le bas après le chargement.
- Barre latérale gauche : navigation au niveau produit (sections, versions) avec bon support clavier et état persistant.
- Colonne principale : 65–80 caractères par ligne, interligne généreux, hiérarchie H2/H3 claire.
- Rail droit (optionnel) : table des matières interne qui met en évidence la section courante et ne saute pas.
- Pied de page : pas une réclame. Restez discret.
Structure recommandée (mobile)
- En‑tête supérieur avec une seule icône de menu.
- La TOC devient un panneau repliable « Sur cette page ».
- La barre latérale devient un tiroir plein écran avec la recherche en haut.
Ce n’est pas une tendance de design. C’est une réduction de la charge cognitive. La plupart des lectures de docs ne sont pas de la « lecture ». C’est de la toilettage : scanner, sauter, vérifier, copier, revenir.
Blague #1 : Une page de docs sans TOC stable, c’est comme un pager sans pile — techniquement toujours un pager, mais qui produit surtout du regret.
Pourquoi ce modèle fonctionne (les mécanismes)
Les utilisateurs restent quand trois choses se produisent :
- Ils savent toujours où ils se trouvent. Les fil d’Ariane, l’élément de nav surligné et la position dans la TOC font cela.
- Ils peuvent prédire où l’information sera. Des titres cohérents et une mise en page stable construisent une carte mentale.
- La page ne leur met pas des bâtons dans les roues. Pas de saut de mise en page, pas d’éléments collants qui recouvrent les titres, pas de saccades de défilement.
« Mise en page de docs » ressemble à une préoccupation front‑end jusqu’à ce que vous voyiez votre équipe de support se transformer en couche de cache humaine parce que les utilisateurs ne trouvent pas ce qui est déjà écrit.
Principes de mise en page non négociables
1) La stabilité prime sur l’ingéniosité
Votre navigation et votre TOC ne doivent pas bouger en fonction de polices qui se chargent tard, de bannières injectées ou d’expériences A/B. Si la page bouge pendant la lecture, vous introduisez des interruptions aléatoires. Les gens ne vont pas signaler un bug ; ils partiront.
Concevez pour une géométrie prévisible. Réservez de l’espace pour tout ce qui pourrait apparaître : badges de version, encadrés, boutons « copier », sélecteurs de langue. Ce n’est pas glamour. Ça marche.
2) Rendre la colonne de contenu lisible par défaut
Lisible ne veut pas dire « texte plus grand ». Ça veut dire :
- Longueur de ligne autour de 65–80 caractères pour le texte courant.
- Interligne autour de 1,5–1,7.
- Style de code évident avec contraste suffisant et règles d’habillage de lignes qui ne détruisent pas les commandes.
- Des titres qui ressemblent à des titres. Ne vous amusez pas trop avec la typographie.
3) La navigation est une dépendance de production
Si votre barre latérale gauche casse, vous avez déployé une panne. Ce n’est pas « juste une UI ». Traitez‑la comme un service critique : testé, surveillé et versionné.
4) La TOC n’est pas décorative ; c’est une surface de contrôle
Le rail droit TOC doit remplir trois fonctions :
- Montrer la structure de la page en un coup d’œil.
- Permettre de sauter sans perdre le contexte.
- Indiquer la progression et la position (mise en évidence de la section active).
Quand la TOC se met en évidence correctement, les utilisateurs font confiance à la page. Quand elle se trompe, les utilisateurs arrêtent de faire confiance à tout.
5) La recherche doit être rapide, ciblée et tolérante
Une recherche de docs qui renvoie des pages marketing n’est pas une recherche ; c’est du sabotage. Ciblez par produit/version, supportez la tolérance aux fautes pour les fautes de frappe courantes, et indexez intelligemment les titres et les blocs de code. L’autocomplétion doit répondre vite, sinon elle devient un tiroir d’ennuis.
6) Chaque interaction doit préserver la position de défilement
Ouvrir la barre latérale, copier du code, changer d’onglets dans des exemples, développer des encadrés — rien de tout cela ne doit faire sauter la page. Préservez le défilement, évitez les pièges de focus et utilisez correctement les ancres internes.
Architecture de l’information qui ne manipule pas l’utilisateur
La mise en page est le bâtiment physique ; l’architecture de l’information est la signalétique. Les deux peuvent être mauvaises d’une manière difficile à formuler mais facile à ressentir.
Privilégiez des chemins peu profonds avec un fort regroupement
Les lecteurs de docs ne parcourent pas votre produit pour le plaisir. Ils essaient d’accomplir une tâche avec un budget temps et un léger sentiment de panique. Gardez la profondeur de navigation raisonnable. Si votre barre latérale nécessite 5 expansions pour atteindre « Rate limiting », l’utilisateur apprendra une autre compétence : partir.
Le versioning appartient à la mise en page, pas au contenu
N’encombrez pas les pages de « Pour v2 seulement » dans le texte. Placez la sélection de version à un endroit prévisible (en‑tête ou barre latérale) et maintenez‑la fixe. Assurez‑vous que le changement de version :
- tente d’atterrir sur la même page dans l’autre version,
- recul en douceur avec un message clair en cas d’échec,
- ne casse pas les URLs partageables.
Faites en sorte que « Sur cette page » corresponde au contenu réel
La TOC doit être générée à partir des titres réels (H2/H3) et ne doit pas inclure des titres décoratifs ou du contenu caché. Si vous ajoutez des titres uniquement pour le style, vous polluerez la TOC et ferez paraître la page plus longue qu’elle ne l’est.
Faits et contexte historique (parce que ce n’est pas né hier)
- Fait 1 : Le modèle « trois colonnes » (nav + contenu + TOC) est devenu courant à mesure que les portails développeurs se sont étendus dans les années 2010, quand les docs monoplates ont commencé à devenir des sites complets.
- Fait 2 : Les travaux de Jakob Nielsen sur l’utilisabilité web dans les années 1990 ont poussé des modèles favorables au scan—paragraphes courts, titres significatifs et navigation évidente—bien avant que « DX » devienne un intitulé de poste.
- Fait 3 : « Above the fold » comptait davantage à l’aube du web à cause des limites de bande passante et rendu ; aujourd’hui, la stabilité de la mise en page et la rapidité d’interaction comptent plus que tout entasser en haut.
- Fait 4 : L’essor du positionnement sticky en CSS moderne a rendu les TOC persistantes nettement plus faciles qu’avec les hack JavaScript d’il y a une décennie.
- Fait 5 : Le Cumulative Layout Shift (CLS) est entré dans la conversation ingénierie grand public avec Core Web Vitals, transformant le ressenti « c’est qui saute » en régression mesurable.
- Fait 6 : La recherche dans les docs s’est améliorée quand les générateurs de sites statiques ont commencé à émettre des données structurées et un balisage de titres cohérent—l’indexation s’est améliorée parce que le HTML était moins chaotique.
- Fait 7 : Le bouton « copier dans le presse‑papier » est devenu courant quand les navigateurs ont standardisé les API clipboard ; avant, de nombreux sites utilisaient des solutions fragiles basées sur Flash ou des contournements instables.
- Fait 8 : L’engouement moderne pour le dark mode répond en partie au fait que les développeurs vivent dans des terminaux toute la journée ; c’est de l’ergonomie et une préférence, pas seulement de l’esthétique.
La performance est de l’UX : budgets, métriques et pièges
En production, vous ne discutez pas avec des graphes de latence. Pour l’UX des docs, vous ne devriez pas discuter avec les métriques de performance non plus. Une page de docs lente n’est pas juste agaçante — elle empêche la compréhension. La mémoire de travail du lecteur n’est pas une file avec une profondeur infinie.
Choisissez les métriques qui corrèlent avec « garder le lecteur en train de défiler »
Pour les pages de docs, je m’intéresse à :
- LCP (Largest Contentful Paint) : le contenu principal apparaît‑t‑il rapidement ?
- CLS : la page reste‑t‑elle immobile pendant le chargement ?
- INP (Interaction to Next Paint) : la page répond‑elle aux interactions (ouvrir la nav, développer des sections, recherche) sans s’imposer ?
- TTFB : faisons‑nous attendre l’utilisateur sur l’origine/CDN ?
- Tâches longues dans le navigateur : bloquons‑nous le thread principal avec du scripting ?
Fixez des budgets et respectez‑les
Une page de docs devrait être moins coûteuse que votre site marketing. Vous ne pouvez pas prétendre « orienté développeur » tout en livrant 900KB de JavaScript pour rendre une page qui est à 95% du texte statique.
Budgets de départ raisonnables :
- < 200KB JavaScript gzippé pour le squelette des docs (idéalement moins)
- < 100KB CSS gzippé
- Polices : variantes minimales, préchargement responsable, avec mécanismes de secours
- Images : généralement aucune au‑dessus du pli ; si présentes, elles doivent avoir largeur/hauteur définis
Une citation, parce que c’est toujours vrai
« L’espoir n’est pas une stratégie. » — Gene Kranz
Pièges de performance spécifiques aux mises en page de docs
- Piège : tout coller. Trop d’éléments collants causent chevauchement, reflow et ancres inutilisables. En‑tête sticky + TOC sticky + barre de cookies sticky = 40% de la fenêtre occupée par la chrome.
- Piège : TOC construite par parsing côté client. Si vous parsez le DOM après le chargement pour construire la TOC, vous risquez des saccades et des ancres incorrectes. Générez la TOC à la construction quand c’est possible.
- Piège : hydratation « utile ». Hydrater une page entière pour quelques composants interactifs, c’est comme provisionner un cluster Kubernetes pour un job cron. Ça marche. C’est aussi un appel à l’aide.
- Piège : polices web sans garde‑fous. Les polices qui se chargent tard provoquent du CLS, et les blocs de code sont particulièrement sensibles : la largeur des caractères change et les lignes se replient différemment.
- Piège : indexation de recherche côté client au chargement. Construire un index de recherche dans le navigateur peut être coûteux. Si vous devez le faire, chargez‑le paresseusement et ne bloquez pas le rendu.
Blague #2 : J’ai vu une fois une page de docs qui nécessitait 12MB de JavaScript pour expliquer comment économiser 12MB de JavaScript.
Tâches pratiques : commandes, sorties, décisions
Vous voulez moins de rebonds ? Mesurez. Vous voulez une mise en page stable ? Prouvez‑le. Voici des tâches réelles que je donnerais à une équipe frontend orientée SRE. Chacune a une commande, une sortie d’exemple, ce que ça signifie et la décision à prendre.
Task 1: Check origin TTFB from a production-like host
cr0x@server:~$ curl -s -o /dev/null -w "namelookup:%{time_namelookup} connect:%{time_connect} ttfb:%{time_starttransfer} total:%{time_total}\n" https://docs.example.com/guides/rate-limits
namelookup:0.007 connect:0.021 ttfb:0.312 total:0.419
Ce que ça signifie : Le Time To First Byte est d’environ 312ms ; le total est de 419ms. Ce n’est pas catastrophique, mais pour des docs vous voulez que ce soit bas et constant.
Décision : Si le TTFB est instable ou >500ms, priorisez la mise en cache CDN, l’optimisation de l’origine et la suppression du rendu dynamique pour du contenu majoritairement statique.
Task 2: Confirm caching headers (are we actually using the CDN?)
cr0x@server:~$ curl -sI https://docs.example.com/guides/rate-limits | egrep -i "cache-control|age|etag|last-modified|cf-cache-status|x-cache"
cache-control: public, max-age=0, must-revalidate
etag: "9b3e-1a2f3c"
age: 0
x-cache: MISS
Ce que ça signifie : Vous forcez la revalidation et vous ratez le cache. Age 0 suggère que l’objet ne reste pas chaud.
Décision : Pour des artefacts de build immuables, distribuez un cache longue durée (avec noms de fichiers hashés) et laissez l’HTML se révalider à moindre coût. Ne handicapez pas le CDN avec « max-age=0 » partout.
Task 3: Inspect TLS and connection reuse (quiet latency tax)
cr0x@server:~$ curl -s -o /dev/null -w "remote_ip:%{remote_ip} ssl_verify:%{ssl_verify_result} http_version:%{http_version}\n" https://docs.example.com/
remote_ip:203.0.113.10 ssl_verify:0 http_version:2
Ce que ça signifie : HTTP/2 est en place ; la vérification TLS est correcte.
Décision : Si vous êtes coincé en HTTP/1.1, vous paierez des connexions supplémentaires sur des pages riches en ressources. Corrigez la configuration edge d’abord ; ce sont habituellement des gains bon marché.
Task 4: Measure real page weight of key docs routes
cr0x@server:~$ curl -s https://docs.example.com/guides/rate-limits | wc -c
186442
Ce que ça signifie : L’HTML fait ~186KB. C’est gros pour une page textuelle ; cela peut inclure du JSON inline, un markup de nav lourd ou trop d’état client.
Décision : Si l’HTML dépasse régulièrement ~100KB pour des pages typiques, auditez la duplication de nav, les données inline inutiles et le markup excessif du générateur.
Task 5: Find uncompressed assets (bandwidth you didn’t mean to spend)
cr0x@server:~$ curl -sI https://docs.example.com/assets/app.js | egrep -i "content-encoding|content-length"
content-length: 842311
Ce que ça signifie : Pas d’en‑tête gzip/brotli visible. L’asset pourrait être non compressé à l’edge ou votre requête n’a pas négocié la compression.
Décision : Activez brotli/gzip et assurez‑vous que le CDN sert les variantes compressées. Si vous ne voyez pas content-encoding, testez avec un en‑tête Accept-Encoding.
Task 6: Verify brotli/gzip negotiation explicitly
cr0x@server:~$ curl -sI -H "Accept-Encoding: br,gzip" https://docs.example.com/assets/app.js | egrep -i "content-encoding|vary|content-length"
vary: Accept-Encoding
content-encoding: br
content-length: 214903
Ce que ça signifie : Brotli fonctionne ; la taille compressée est ~215KB, ce qui reste volumineux mais pas tragique.
Décision : Si le JS compressé dépasse votre budget, réduisez la portée d’hydratation, fractionnez les bundles et retirez les dépendances du « squelette docs » qui appartiennent à l’application, pas aux docs.
Task 7: Check Core Web Vitals in your monitoring pipeline (synthetic)
cr0x@server:~$ lighthouse https://docs.example.com/guides/rate-limits --quiet --chrome-flags="--headless" --only-categories=performance
Performance: 71
First Contentful Paint: 1.8 s
Largest Contentful Paint: 3.3 s
Cumulative Layout Shift: 0.19
Total Blocking Time: 420 ms
Ce que ça signifie : LCP est un peu lent, le CLS est trop élevé pour une page de lecture, et le blocage du thread principal est significatif.
Décision : Attaquez le CLS en priorité (c’est une friction pure), puis réduisez le temps d’exécution du JS (TBT/INP). LCP s’améliore souvent en conséquence.
Task 8: Identify layout shift culprits via headless trace (quick signal)
cr0x@server:~$ lighthouse https://docs.example.com/guides/rate-limits --quiet --chrome-flags="--headless" --output=json --output-path=/tmp/lh.json
cr0x@server:~$ jq -r '.audits["cumulative-layout-shift"].details.items[]? | "\(.node.selector) \(.score)"' /tmp/lh.json | head
.header-announcement 0.07
code pre 0.05
.sidebar 0.03
Ce que ça signifie : La barre d’annonce, les blocs de code et la barre latérale provoquent des décalages.
Décision : Réservez l’espace pour l’en‑tête ; définissez des métriques de secours pour les polices de code ; verrouillez la largeur de la barre latérale ; définissez les dimensions pour images et embeds.
Task 9: Check for render-blocking CSS/JS (the classic “why is text late?”)
cr0x@server:~$ curl -s https://docs.example.com/guides/rate-limits | grep -Eo '<script[^>]+>' | head -n 5