Große Websites
Das NDJSON-Format, das Fortsetzungsjournal, Listen- und Sitemap-Modus, der Benchmark mit 200 000 Seiten und die von 3.16 bis 3.21 hinzugefügten Crawl-Leitplanken.
Was gemessen wurde
Die Versionen 3.16 bis 3.21 bildeten ein Skalierungsprogramm in sechs Schritten, jeder gemessen auf einer synthetischen Site, die lokal von bench/site.mjs erzeugt wird (N Seiten, spontan generiert, rund 60 Template-Links und 40 deterministische Links pro Seite, 404s, Weiterleitungen, Beinahe-Duplikate; eine echte Website wird nie aufgerufen).
| Messung | Wert |
|---|---|
| Gecrawlte Seiten (synthetische Site) | 200.000 |
| Interne Links | 19.900.000 |
| Crawl und Analyse | 2.086 s |
| Seiten pro Sekunde (ca.) | 96 |
| Speicherdauer | 38 s |
| Gespeicherte Datei (NDJSON gzip) | 62,5 MB |
| Spitzenspeicher | 2,7 GB |
| Standard-Seitenbudget | 500 |
Gemessen mit npm run bench -- --pages 200000 auf einer lokalen synthetischen Site, erzeugt von bench/site.mjs (keine echte Website wird aufgerufen). Ihre Zahlen hängen von Ihrem Rechner, der Website und den Optionen ab (JavaScript-Rendering ist deutlich langsamer).
Das Standardbudget ist bewusst niedrig. Heben Sie Optionen → Limits → Crawl-Gesamtzahl für eine große Website an, bleiben Sie auf einem Kundenserver bei 2 bis 5 Threads, und denken Sie daran, dass JavaScript-Rendering deutlich langsamer ist als rohes HTML.
Die sechs Schritte
- 3.16, kein Absturz mehr am Ende: Ein
Math.min(...)über einen Wert pro URL löste jenseits von etwa 125 000 URLs nach Stunden Crawl Maximum call stack size exceeded aus; vierzehn kleine Korrekturen beseitigten ihn und die quadratischen Schleifen (Korrekturaufgaben, KI-Beispiele, Links auf Weiterleitungen, nächstgelegene URL für 404s, Tabellensortierung, Ordnerzählung). Crawl-Dateien werden atomar geschrieben (temporäre Datei, dann Umbenennung). - 3.17, ein kompakter Linkgraph: Links liegen in Typed-Array-Spalten (URLs und Ankertexte einmal interniert, 14 Bytes pro Link), und die Analyse läuft auf einem CSR-Graphen. Gemessen an 50 000 Seiten × 100 Links: Linkspeicher 690 MB → 55 MB, Analyse 29 s / 2,5 GB → 5,5 s / 647 MB, identische Ergebnisse.
- 3.18, ein Crawl, der laufend geschrieben wird: Ergebnisse werden als gezipptes NDJSON gespeichert (
.jsonl.gz, ein JSON-Objekt pro Zeile, Links in Paketen), als Streams geschrieben und gelesen; der Verlauf liest nur die erste Zeile. Ein Fortsetzungsjournal hält jede eingereihte URL und jede fertige Seite fest;--resume(oder der Startbildschirm) setzt einen unterbrochenen Crawl dort fort, wo er stand. Alte.json-Crawls öffnen weiterhin. - 3.19, eine Analyse, die skaliert: Jede Seite wird auf Beinahe-Duplikate verglichen (die alte Prüfung hielt bei 5 000 Seiten an, ohne es zu sagen), mit einer exakten Suche per Bändern auf dem 64-Bit-simhash; die Kannibalisierung läuft in linearer Zeit; die Linkzähler der Segmente werden in einem Durchlauf berechnet.
- 3.20, der Browser erhält nie den ganzen Crawl: Der Server behält den Crawl und seinen Graphen; der Browser erhält ein leichtes Ergebnis als Stream und fragt den Rest bei Bedarf an (die Links einer Seite seitenweise zu 200, der vollständige Seitendatensatz per Klick, die Kanten der Karte nur für die angezeigten Knoten, der Vergleich serverseitig berechnet). Import und Export laufen über den Server.
- 3.21, Crawl-Leitplanken: Das Seitenbudget zählt tatsächlich heruntergeladene Seiten; URL-Parameter werden sortiert und Tracking-Parameter standardmäßig entfernt; Facetten-Fallen werden gemeldet; eine unerreichbare robots.txt verbietet alles, wie RFC 9309 verlangt, mit einem ausdrücklichen Ausweg; 5xx und Netzabbrüche erhalten einen verzögerten Neuversuch; Antwortkörper werden begrenzt; ein abgestürztes Chrome wird neu gestartet und gemeldet; eine durchdrehende Regex wird in einem Worker abgebrochen; der Listenmodus geht bis 500 000 URLs, und
--sitemapcrawlt genau eine Sitemap.
Formate
- Gespeicherter Crawl (
.jsonl.gz): Zeile 1 ist der Kopf (Meta und Zusammenfassung), dann eine Zeile pro Problem, eine pro Seite, URLs, Ankertexte und Links in Paketen zu 100 000 (spaltenorientiert), dann Bilder, externe Links, Weiterleitungen, defekte Links. Keine Zeile ist größer als wenige Megabyte, egal wie groß die Website ist. - Fortsetzungsjournal (
.ndjson, nur anhängend): eine Zeilestart(URL, Optionen), eine Zeileqpro eingereihter URL, eine Zeileppro verarbeiteter Seite mit ihren Links und Bildern. Ein harter Abbruch verliert nur die letzten Sekunden. - Nach dem Crawl bearbeitete Segmente gehen in eine kleine Nebendatei
<name>.segments.json; der Crawl wird nie neu geschrieben. - Alte
.json-Exporte (Format 1 und 2) werden erkannt und öffnen weiterhin.
Listen- und Sitemap-Modus
Der Listen-Modus crawlt genau die URLs, die Sie angeben (in der App eingefügt, --list file.txt in der CLI, urls für Agenten), bis zu 500 000, ohne Links zu folgen; die interne Verlinkung ist dann nicht gemessen. Der Sitemap-Modus (--sitemap URL, sitemapUrl, sitemap_url) liest eine Sitemap oder einen Sitemap-Index und crawlt genau deren URLs, dedupliziert und normalisiert. In beiden Modi wird die robots.txt einmal pro Host gelesen.
Leitplanken, die Sie kennen sollten
- Budget:
maxPageszählt heruntergeladene Seiten; von robots.txt blockierte URLs werden aufgezeichnet, verbrauchen es aber nicht. Die Entdeckung bleibt im Speicher begrenzt (4 × das Budget). - Parameter:
?a=1&b=2und?b=2&a=1sind eine Seite;utm_*,gclid,fbclid,msclkid,mc_cid,srsltid,_ga… werden entfernt.--keep-paramsstellt das rohe Verhalten wieder her. - Facetten: Ein Pfad, der 200 Parametervarianten erzeugt, wird einmal gemeldet (bis zu 20 Pfade).
- robots.txt mit 5xx oder unerreichbar: Alles ist verboten, mit einer Warnung;
--robots-unavailable allowoder der Modus melden / ignorieren lassen den Crawl durch. - Rendering: Chrome wird alle 500 gerenderten Seiten und einmal nach einem Absturz neu gestartet; ein zweiter Absturz wird gemeldet, statt Seiten still ungerendert zu lassen.
- Antworten: Körper werden als Streams gelesen und oberhalb von
maxPageSizeKbverworfen; Sitemaps und robots.txt werden durchmaxSitemapKb(50 MB) begrenzt. - Sicherheit: Benutzerdefinierte Header werden im Browser nicht mehr gespeichert, genau wie das HTTP-Passwort.
Bekannte Lücken
Die URL-Listen der Probleme wandern noch vollständig zum Browser (die Seite Probleme, die Korrektur-Engine, die Segmente und die Kartenfarbe nach Problem); sie zu paginieren ist die nächste Verfeinerung, unterhalb von 200 000 Seiten nicht nötig. Das Öffnen einer Datei über die Schaltfläche Importieren lädt sie auf den Server hoch, der den ganzen Crawl im Speicher hält, genau wie nach einem Crawl. Reproduzieren Sie den Benchmark selbst mit npm run bench -- --pages 200000 (er braucht rund 8 GB Heap, vom Skript gesetzt).