Sitios grandes

El formato NDJSON, el diario de reanudación, los modos lista y sitemap, el benchmark de 200 000 páginas y las salvaguardas de rastreo añadidas de la 3.16 a la 3.21.

Qué se midió

Las versiones 3.16 a 3.21 fueron un programa de escalado en seis pasos, cada uno medido en un sitio sintético generado localmente por bench/site.mjs (N páginas generadas al vuelo, unos 60 enlaces de plantilla y 40 enlaces deterministas por página, 404, redirecciones, casi duplicados; nunca se accede a ningún sitio real).

MedidaValor
Páginas rastreadas (sitio sintético)200.000
Enlaces internos19.900.000
Rastreo y análisis2086 s
Páginas por segundo (aprox.)96
Tiempo de guardado38 s
Archivo guardado (NDJSON gzip)62,5 MB
Memoria máxima2,7 GB
Presupuesto de páginas por defecto500

Medido con npm run bench -- --pages 200000 en un sitio sintético local generado por bench/site.mjs (no se accede a ningún sitio real). Tus cifras dependen de tu máquina, del sitio y de las opciones (el renderizado JavaScript es mucho más lento).

El presupuesto por defecto es deliberadamente bajo. Aumenta Opciones → Límites → Total del rastreo para un sitio grande, mantén entre 2 y 5 hilos en el servidor de un cliente, y recuerda que el renderizado JavaScript es mucho más lento que el HTML bruto.

Los seis pasos

  1. 3.16, se acabaron los fallos al final: un Math.min(...) sobre un valor por URL lanzaba Maximum call stack size exceeded a partir de unas 125 000 URL, tras horas de rastreo; catorce correcciones pequeñas lo eliminaron junto con los bucles cuadráticos (tareas de corrección, ejemplos para la IA, enlaces a redirecciones, URL más cercana para los 404, ordenación de tablas, recuento de carpetas). Los archivos de rastreo se escriben de forma atómica (archivo temporal y luego renombrado).
  2. 3.17, un grafo de enlaces compacto: los enlaces viven en columnas de arrays tipados (URL y textos de ancla almacenados una sola vez, 14 bytes por enlace) y el análisis se ejecuta sobre un grafo CSR. Medido en 50 000 páginas × 100 enlaces: almacenamiento de enlaces 690 MB → 55 MB, análisis 29 s / 2,5 GB → 5,5 s / 647 MB, resultados idénticos.
  3. 3.18, un rastreo escrito sobre la marcha: los resultados se guardan en NDJSON gzip (.jsonl.gz, un objeto JSON por línea, enlaces por bloques), escritos y leídos en flujo; el historial solo lee la primera línea. Un diario de reanudación anota cada URL encolada y cada página hecha; --resume (o la pantalla de inicio) retoma un rastreo interrumpido donde se detuvo. Los rastreos .json antiguos siguen abriéndose.
  4. 3.19, un análisis que escala: todas las páginas se comparan en busca de casi duplicados (la antigua comprobación se detenía en 5 000 páginas sin decirlo) con una búsqueda exacta por bandas sobre el simhash de 64 bits; la canibalización se ejecuta en tiempo lineal; los contadores de enlaces por segmento se calculan en una sola pasada.
  5. 3.20, el navegador nunca recibe el rastreo entero: el servidor conserva el rastreo y su grafo; el navegador recibe un resultado ligero en flujo y pide el resto bajo demanda (los enlaces de una página paginados de 200 en 200, la ficha completa de la página al hacer clic, las aristas del mapa solo para los nodos mostrados, la comparación calculada en el servidor). La importación y la exportación pasan por el servidor.
  6. 3.21, salvaguardas de rastreo: el presupuesto de páginas cuenta las páginas realmente descargadas; los parámetros de URL se ordenan y los parámetros de seguimiento se eliminan por defecto; las trampas de facetas se señalan; un robots.txt inaccesible lo prohíbe todo como exige la RFC 9309, con una salida explícita; los 5xx y los cortes de red reciben un reintento diferido; los cuerpos de respuesta se acotan; un Chrome que muere se reinicia y se señala; una regex desbocada se interrumpe en un worker; el modo lista sube a 500 000 URL y --sitemap rastrea exactamente un sitemap.

Formatos

  • Rastreo guardado (.jsonl.gz): la línea 1 es la cabecera (meta y resumen), luego una línea por problema, una por página, URL, anclas y enlaces por bloques de 100 000 (en columnas), y después imágenes, enlaces externos, redirecciones, enlaces rotos. Ninguna línea supera unos pocos megabytes, sea cual sea el sitio.
  • Diario de reanudación (.ndjson, solo anexado): una línea start (URL, opciones), una línea q por URL encolada, una línea p por página procesada con sus enlaces e imágenes. Una parada brusca solo pierde los últimos segundos.
  • Segmentos editados después del rastreo: van a un pequeño archivo adyacente <nombre>.segments.json; el rastreo nunca se reescribe.
  • Las exportaciones .json antiguas (formatos 1 y 2) se detectan y siguen abriéndose.

Modos lista y sitemap

El modo Lista rastrea exactamente las URL que le das (pegadas en la aplicación, --list archivo.txt en la CLI, urls para los agentes), hasta 500 000, sin seguir los enlaces; el enlazado interno queda entonces no medido. El modo Sitemap (--sitemap URL, sitemapUrl, sitemap_url) lee un sitemap o un índice de sitemaps y rastrea exactamente sus URL, deduplicadas y normalizadas. En ambos modos, robots.txt se lee una vez por host.

Salvaguardas que conviene conocer

  • Presupuesto: maxPages cuenta las páginas descargadas; las URL bloqueadas por robots.txt se registran pero no lo consumen. El descubrimiento se mantiene acotado en memoria (4 × el presupuesto).
  • Parámetros: ?a=1&b=2 y ?b=2&a=1 son una sola página; utm_*, gclid, fbclid, msclkid, mc_cid, srsltid, _ga… se eliminan. --keep-params restablece el comportamiento bruto.
  • Facetas: una ruta que produce 200 variantes de parámetros se señala una vez (hasta 20 rutas).
  • robots.txt en 5xx o inaccesible: todo está prohibido, con una advertencia; --robots-unavailable allow o el modo informar / ignorar dejan pasar el rastreo.
  • Renderizado: Chrome se reinicia cada 500 páginas renderizadas y una vez si muere; una segunda muerte se señala en lugar de dejar páginas sin renderizar en silencio.
  • Respuestas: cuerpos leídos en flujo y abandonados más allá de maxPageSizeKb; sitemaps y robots.txt acotados por maxSitemapKb (50 MB).
  • Seguridad: las cabeceras personalizadas ya no se recuerdan en el navegador, igual que la contraseña HTTP.

Limitaciones conocidas

Las listas de URL de los problemas todavía viajan enteras al navegador (la página de problemas, el motor de corrección, los segmentos y el color del mapa por problema); paginarlas es el próximo refinamiento, innecesario por debajo de 200 000 páginas. Abrir un archivo desde el botón Importar lo sube al servidor, que mantiene el rastreo entero en memoria, igual que después de un rastreo. Reproduce el benchmark tú mismo con npm run bench -- --pages 200000 (necesita unos 8 GB de heap, configurados por el script).

Versión 3.21.0 Las tablas de referencia y el historial de versiones se generan desde el repositorio de Arachnide (commit f287355). Editar esta página en GitHub