Gros sites

Le format NDJSON, le journal de reprise, les modes liste et sitemap, le benchmark à 200 000 pages et les garde-fous de crawl ajoutés de la 3.16 à la 3.21.

Ce qui a été mesuré

Les versions 3.16 à 3.21 forment un programme de passage à l’échelle en six étapes, chacune mesurée sur un site synthétique généré localement par bench/site.mjs (N pages générées à la volée, environ 60 liens de gabarit et 40 liens déterministes par page, des 404, des redirections, des quasi-doublons ; aucun site réel n’est jamais sollicité).

MesureValeur
Pages crawlées (site synthétique)200 000
Liens internes19 900 000
Crawl et analyse2 086 s
Pages par seconde (environ)96
Temps de sauvegarde38 s
Fichier enregistré (NDJSON gzip)62,5 MB
Mémoire maximale2,7 GB
Budget de pages par défaut500

Mesuré avec npm run bench -- --pages 200000 sur un site synthétique local généré par bench/site.mjs (aucun site réel n’est sollicité). Vos chiffres dépendent de votre machine, du site et des options (le rendu JavaScript est beaucoup plus lent).

Le budget par défaut est volontairement bas. Relevez Options → Limites → Total du crawl pour un gros site, gardez 2 à 5 threads sur un serveur client, et rappelez-vous que le rendu JavaScript est beaucoup plus lent que le HTML brut.

Les six étapes

  1. 3.16, plus de plantage à la fin : un Math.min(...) sur une valeur par URL levait Maximum call stack size exceeded au-delà d’environ 125 000 URL, après des heures de crawl ; quatorze petits correctifs l’ont supprimé ainsi que les boucles quadratiques (tâches de correction, exemples pour l’IA, liens vers des redirections, URL la plus proche pour les 404, tri des tables, comptage des dossiers). Les fichiers de crawl sont écrits de façon atomique (fichier temporaire puis renommage).
  2. 3.17, un graphe de liens compact : les liens vivent dans des colonnes de tableaux typés (URL et textes d’ancre internés une fois, 14 octets par lien) et l’analyse tourne sur un graphe CSR. Mesuré sur 50 000 pages × 100 liens : stockage des liens 690 Mo → 55 Mo, analyse 29 s / 2,5 Go → 5,5 s / 647 Mo, résultats identiques.
  3. 3.18, un crawl écrit au fil de l’eau : les résultats sont enregistrés en NDJSON gzip (.jsonl.gz, un objet JSON par ligne, liens par morceaux), écrits et lus en flux ; l’historique ne lit que la première ligne. Un journal de reprise enregistre chaque URL mise en file et chaque page traitée ; --resume (ou l’écran d’accueil) reprend un crawl interrompu là où il s’est arrêté. Les anciens crawls .json s’ouvrent toujours.
  4. 3.19, une analyse qui passe à l’échelle : toutes les pages sont comparées pour les quasi-doublons (l’ancien contrôle s’arrêtait à 5 000 pages sans le dire) avec une recherche exacte par bandes sur le simhash 64 bits ; la cannibalisation tourne en temps linéaire ; les compteurs de liens par segment sont calculés en une passe.
  5. 3.20, le navigateur ne reçoit plus jamais le crawl entier : le serveur garde le crawl et son graphe ; le navigateur reçoit un résultat allégé en flux et demande le reste à la demande (les liens d’une page paginés par 200, la fiche complète d’une page au clic, les arêtes de la carte pour les nœuds affichés seulement, la comparaison calculée côté serveur). Import et export passent par le serveur.
  6. 3.21, garde-fous de crawl : le budget de pages compte les pages réellement téléchargées ; les paramètres d’URL sont triés et les paramètres de suivi supprimés par défaut ; les pièges à facettes sont signalés ; un robots.txt injoignable interdit tout comme l’exige la RFC 9309, avec une porte de sortie explicite ; les 5xx et coupures réseau ont droit à un essai différé ; les corps de réponse sont bornés ; un Chrome qui meurt est redémarré et signalé ; une regex qui s’emballe est interrompue dans un worker ; le mode liste monte à 500 000 URL et --sitemap crawle exactement un sitemap.

Formats

  • Crawl enregistré (.jsonl.gz) : la ligne 1 est l’en-tête (meta et résumé), puis une ligne par problème, une par page, URL, ancres et liens par morceaux de 100 000 (en colonnes), puis images, liens externes, redirections, liens cassés. Aucune ligne ne dépasse quelques mégaoctets, quel que soit le site.
  • Journal de reprise (.ndjson, ajout seul) : une ligne start (URL, options), une ligne q par URL mise en file, une ligne p par page traitée avec ses liens et images. Un arrêt brutal ne perd que les dernières secondes.
  • Segments modifiés après le crawl : un petit fichier à côté <nom>.segments.json ; le crawl n’est jamais réécrit.
  • Les anciens exports .json (formats 1 et 2) sont détectés et s’ouvrent toujours.

Modes liste et sitemap

Le mode Liste crawle exactement les URL que vous donnez (collées dans l’application, --list fichier.txt en CLI, urls pour les agents), jusqu’à 500 000, sans suivre les liens ; le maillage interne est alors non mesuré. Le mode Sitemap (--sitemap URL, sitemapUrl, sitemap_url) lit un sitemap ou un index de sitemaps et crawle exactement ses URL, dédoublonnées et normalisées. Dans les deux modes, le robots.txt est lu une fois par hôte.

Garde-fous à connaître

  • Budget : maxPages compte les pages téléchargées ; les URL bloquées par robots.txt sont enregistrées mais ne le consomment pas. La découverte reste bornée en mémoire (4 × le budget).
  • Paramètres : ?a=1&b=2 et ?b=2&a=1 sont une seule page ; utm_*, gclid, fbclid, msclkid, mc_cid, srsltid, _ga… sont supprimés. --keep-params rétablit le comportement brut.
  • Facettes : un chemin qui produit 200 variantes de paramètres est signalé une fois (jusqu’à 20 chemins).
  • robots.txt en 5xx ou injoignable : tout est interdit, avec un avertissement ; --robots-unavailable allow ou le mode signaler / ignorer laissent passer le crawl.
  • Rendu : Chrome redémarré toutes les 500 pages rendues et une fois s’il meurt ; une seconde mort est signalée au lieu de pages silencieusement non rendues.
  • Réponses : corps lus en flux et abandonnés au-delà de maxPageSizeKb ; sitemaps et robots.txt bornés par maxSitemapKb (50 Mo).
  • Sécurité : les en-têtes personnalisés ne sont plus mémorisés dans le navigateur, comme le mot de passe HTTP.

Limites connues

Les listes d’URL des problèmes voyagent encore entières vers le navigateur (la page Problèmes, le moteur de correction, les segments et la couleur de la carte par problème) ; les paginer est le prochain raffinement, inutile sous 200 000 pages. Ouvrir un fichier depuis le bouton Importer l’envoie au serveur, qui garde le crawl entier en mémoire, comme après un crawl. Reproduisez le benchmark vous-même avec npm run bench -- --pages 200000 (il a besoin d’environ 8 Go de tas, réglé par le script).

Version 3.21.0 Les tables de référence et le journal des versions sont générés depuis le dépôt d’Arachnide (commit f287355). Modifier cette page sur GitHub