Unterschiede zwischen zwei HTML-Dateien erkennen

Zwei HTML-Dateien können im Browser identisch gerendert werden, sich aber an Dutzenden von Stellen im Quellcode unterscheiden. Leerzeichen rund um Tags, die Reihenfolge der Attribute, HTML-Entitäten und die Syntax selbstschließender Elemente sind die häufigsten Ursachen. Ein einfacher Textdiff markiert jedes davon als Änderung und verbirgt so das, was wirklich wichtig ist. Dieser Leitfaden zeigt, wie Sie ein sauberes Ergebnis erhalten.

Wenn Sie direkt zum Tool springen möchten, können Sie auf unserer HTML-Vergleichsseite zwei Dateien einfügen und den Diff im Browser sehen, ohne Installation. Der Rest dieses Artikels erklärt, worauf Sie im Ergebnis achten sollten.

Warum HTML-Diffs so viel Rauschen erzeugen

HTML ist kein zeilenorientiertes Format. Ein Absatz kann in einer langen Zeile oder über zehn Zeilen verteilt stehen, beides ist gültig. Die meisten Editoren, Code-Formatter und CMSe formatieren HTML beim Speichern neu, was bedeutet, dass eine einzelne Wortänderung Dutzende von neu formatierten Zeilen zur Folge haben kann. Der Diff sieht diese als geänderte Zeilen, nicht als "ein Wort geändert."

Der WHATWG HTML Living Standard legt fest, wie Browser HTML parsen, sagt aber nicht, wie es zurück in Text serialisiert werden soll. Zwei Werkzeuge können strukturell identisches HTML erzeugen, das als Rohtext ganz anders aussieht.

Vier Dinge erklären den Großteil des Rauschens:

  • Leerzeichen zwischen und innerhalb von Tags
  • Attributreihenfolge (Browser erfordern keine bestimmte Reihenfolge)
  • HTML-Entitäten vs. wörtliche Zeichen
  • Syntax leerer Elemente (<br> vs. <br />)

Leerzeichen: die größte Quelle falscher Positive

In den meisten Kontexten werden aufeinanderfolgende Leerzeichen in HTML beim Rendern im Browser zu einem einzigen Leerzeichen zusammengefasst. Das bedeutet, dass diese beiden Schnipsel identisch angezeigt werden:

<!-- Version 1 -->
<p>Free text comparison tool.</p>

<!-- Version 2 -->
<p>
  Free text comparison tool.
</p>

Ein einfacher Textdiff markiert beide Zeilen als geändert. Sie haben sich in keinem bedeutsamen Sinne geändert. Entscheiden Sie vor dem Vergleich, ob Leerzeichen für Ihren Anwendungsfall wichtig sind. Bei E-Mail-Vorlagen oder PDF-Renderern kann das gelegentlich der Fall sein. Für die meisten Webseiten gilt das nicht.

Die beste Lösung ist, beide Dateien vor dem Diff durch einen Formatter wie Prettier mit derselben Konfiguration laufen zu lassen. Das normalisiert Einrückung, Zeilenlänge und Abstände in einem Schritt. Sobald beide Dateien denselben Formatierungsstil teilen, markiert ein einfacher Textdiff nur noch echte Inhaltsänderungen.

Attributreihenfolge

Die HTML-Spezifikation schreibt keine bestimmte Reihenfolge der Attribute vor. <div id="main" class="container"> und <div class="container" id="main"> sind dasselbe Element. Ein Zeilendiff behandelt sie aber als unterschiedliche Zeilen. Das tritt besonders häufig auf, wenn Templates von verschiedenen Werkzeugen generiert werden oder wenn jemand einen Auto-Formatter ausführt, der Attribute alphabetisch sortiert.

Laut der WHATWG-Parsing-Spezifikation sind Attribute am selben Element per Definition ungeordnet. Ein Diff, der eine Attribut-Umordnung als Änderung meldet, ist technisch korrekt, aber selten nützlich. Normalisieren Sie die Attributreihenfolge in beiden Dateien vor dem Vergleich, wenn das Rauschen erzeugt.

HTML-Entitäten

&amp;, &lt;, &gt;, &nbsp;, numerische Referenzen wie &#8212; — das sind alles Möglichkeiten, Zeichen im HTML-Quellcode zu kodieren. Zwei Dateien können dasselbe Zeichen unterschiedlich kodieren und dieselbe Seite rendern. Ein Textdiff sieht &amp; und & als unterschiedliche Zeichenketten, obwohl beide ein kaufmännisches Und im Browser erzeugen.

Wenn Entitätsunterschiede Ihren Diff unübersichtlich machen, führen Sie beide Dateien vor dem Vergleich durch einen HTML-Parser, der Entitäten normalisiert. Die eigene DOMParser-API des Browsers ist eine zuverlässige Möglichkeit, das in JavaScript zu tun: beide Zeichenketten parsen, mit innerHTML zurück serialisieren und das Ergebnis vergleichen.

Leere Elemente

In HTML5 benötigen leere Elemente (Elemente ohne Kinder) keinen abschließenden Schrägstrich. <br>, <br/> und <br /> sind alle gültig und werden alle identisch geparst. Dasselbe gilt für <img>, <input>, <meta> und den Rest. Wenn eine Datei XHTML-artige selbstschließende Schrägstriche verwendet und die andere reine HTML5-Syntax, markiert ein Textdiff jedes dieser Elemente.

Die vollständige Liste der leeren Elemente auf MDN umfasst alle 14. Eine schnelle Suche nach /> in der Diff-Ausgabe zeigt, wie viel des Rauschens auf selbstschließende Syntax zurückzuführen ist.

Ein konkretes Beispiel

Hier ist ein realistisches Vorher-Nachher für einen Site-Header. Drei Dinge haben sich geändert: dem Header wurde eine CSS-Klasse hinzugefügt, das Ziel des Home-Links wurde korrigiert und ein Kontakt-Link wurde hinzugefügt.

<!-- Version 1 -->
<header class="site-header">
  <nav>
    <a href="/home" class="nav-link active">Home</a>
    <a href="/about" class="nav-link">About</a>
  </nav>
</header>

<!-- Version 2 -->
<header class="site-header sticky-top">
  <nav>
    <a href="/" class="nav-link active">Home</a>
    <a href="/about" class="nav-link">About</a>
    <a href="/contact" class="nav-link">Contact</a>
  </nav>
</header>

Fügen Sie beide in das HTML-Vergleichstool ein, und der Diff hebt genau diese drei Zeilen hervor: das Header-Klassen-Attribut, den Home-href und den neuen Anker-Tag. Kein Rauschen, weil Einrückung und Formatierung zwischen den beiden Versionen konsistent sind.

Was sich im obigen Beispiel geändert hat
Element Version 1 Version 2 Art der Änderung
<header> class="site-header" class="site-header sticky-top" Klasse hinzugefügt
Home-Link href="/home" href="/" Pfad korrigiert
Kontakt-Link Nicht vorhanden <a href="/contact">Contact</a> Hinzugefügt

Wann sollte man vor dem Vergleich normalisieren?

Nicht jeder HTML-Vergleich benötigt Normalisierung. Wenn Sie zwei Dateien vergleichen, die Sie selbst mit denselben Editor-Einstellungen geschrieben haben, reicht ein einfacher Textdiff meist aus. Normalisierung lohnt sich, wenn:

  • Eine Datei aus einem CMS-Export stammt und die andere aus Ihrem Editor
  • Ein Build-Tool eine Datei neu formatiert hat, die andere aber nicht
  • Sie minifiziertes HTML mit hübsch formatiertem HTML vergleichen
  • Sie eine HTML-E-Mail-Vorlage von einem externen Absender prüfen

Der W3C Markup Validation Service ist nützlich, um sicherzustellen, dass beide Dateien korrekt geparst werden, bevor Sie sie vergleichen. Eine Datei mit einer defekten Tag-Struktur erzeugt einen irreführenden Diff, weil der Parser Fehler auf seine eigene Weise behebt und zwei Parser unterschiedlich reagieren können.

Generiertes HTML vergleichen

Server-seitig gerenderte Frameworks (Angular, Next.js, Rails) betten oft Zeitstempel, Nonces oder zufällige Bezeichner in die HTML-Ausgabe ein. Zwei Renderings derselben Seite unterscheiden sich in diesen Zeilen, auch wenn der Inhalt identisch ist. Wenn Sie generiertes HTML vergleichen, entfernen oder normalisieren Sie diese Felder vor dem Diff.

Die zugrundeliegende Diff-Engine dieser Website ist Googles diff-match-patch (Apache 2.0), die auf Rohtext arbeitet. Sie parst kein HTML, markiert also Formatierungsunterschiede zusammen mit Inhaltsunterschieden. Deshalb ist vorheriges Normalisieren wichtig. Für die meisten Zwecke liefert das direkte Einfügen der beiden Dateien in wenigen Sekunden ein ausreichend nützliches Ergebnis. Unser XML-Vergleichstool lohnt sich ebenfalls, wenn Ihr HTML wohlgeformtes XHTML ist, da XML-bewusstes Diffing Namespaces und Attributreihenfolgen korrekt behandelt.

Häufig gestellte Fragen

Warum zeigt mein HTML-Diff Hunderte von Änderungen, obwohl ich nur eine Zeile geändert habe?
Fast immer ist es eine Formatierungsänderung. Wenn Ihr Editor oder ein Build-Tool die Datei beim Speichern neu formatiert hat (Einrückung geändert, lange Zeilen umgebrochen oder Attribute neu angeordnet), sieht ein einfacher Textdiff jede neu formatierte Zeile als Änderung. Führen Sie beide Dateien zuerst durch denselben Formatter, dann vergleichen Sie. Die echte Änderung wird die einzige verbleibende Zeile sein.
Ist die Reihenfolge der Attribute in HTML wichtig?
Nicht für den Browser. Der HTML Living Standard schreibt keine bestimmte Reihenfolge der Attribute vor, und Browser parsen sie korrekt, unabhängig von der Reihenfolge. Einige Linter und Formatter sortieren Attribute als Stilregel alphabetisch, was dazu führen kann, dass zwei semantisch identische Dateien in einem Textdiff unterschiedlich aussehen. Wenn die Attributreihenfolge Rauschen verursacht, normalisieren Sie beide Dateien mit demselben Formatter vor dem Vergleich.
Was ist der Unterschied zwischen &amp;amp; und & im HTML-Quellcode?
Beide erzeugen ein kaufmännisches Und, wenn der Browser die Seite rendert. Im HTML-Quellcode ist &amp; die als Entität kodierte Form und & ist das wörtliche Zeichen. Technisch sollte & in Attributwerten gemäß der Spezifikation als &amp; kodiert werden, aber Browser akzeptieren beide. Ein Textdiff behandelt sie als unterschiedliche Zeichenketten. Wenn die Entitätskodierung Rauschen erzeugt, parsen Sie beide Dateien mit einer Bibliothek oder dem DOMParser des Browsers und serialisieren Sie sie vor dem Vergleich zurück.
Kann ich minifiziertes HTML mit hübsch formatiertem HTML vergleichen?
Ja, aber Sie sollten die minifizierte Datei zuerst hübsch formatieren. Der Vergleich von Minifiziertem mit Formatiertem ergibt ein Ergebnis, bei dem fast jede Zeile geändert erscheint, weil Minifizierung alle Leerzeichen entfernt, die der Formatter hinzugefügt hat. Führen Sie die minifizierte Datei durch Prettier oder einen äquivalenten Formatter, dann vergleichen Sie. Die bedeutsamen Änderungen sind ohne das Leerzeichenrauschen sichtbar.
Wie vergleiche ich nur einen Teil einer HTML-Datei, z.B. eine bestimmte Komponente?
Extrahieren Sie den relevanten Abschnitt aus beiden Dateien und fügen Sie nur diesen in das Diff-Tool ein. Wenn Sie beispielsweise Änderungen an einer Navigationskomponente prüfen, kopieren Sie nur den <nav>-Block aus jeder Datei. Das Vergleichen des gesamten Dokuments, wenn Sie sich nur für einen Abschnitt interessieren, fügt Rauschen aus nicht verwandten Teilen der Seite hinzu.
Erscheinen HTML-Kommentare in einem Diff?
Ja. Ein textbasierter Diff enthält alles in der Datei, einschließlich Kommentare. Wenn eine Version einen Kommentarblock hat, den die andere entfernt hat, oder wenn ein Entwickler einen Kommentar aktualisiert hat, wird der Diff das anzeigen. Das ist in der Regel nützlich: ein entfernter Kommentar signalisiert oft eine bewusste Bereinigung. Wenn Sie Kommentare ignorieren möchten, entfernen Sie sie aus beiden Dateien vor dem Vergleich.

Bereit, Ihre HTML-Dateien zu vergleichen? Fügen Sie beide in das kostenlose HTML-Vergleichstool ein und sehen Sie die Unterschiede nebeneinander hervorgehoben, kein Konto erforderlich.