Hur du hittar skillnader mellan två HTML-filer

Två HTML-filer kan renderas identiskt i en webbläsare men ändå skilja sig på dussintals ställen i källkoden. Blanksteg runt taggar, ordningen på attribut, HTML-entiteter och självstängande syntax är de vanligaste bovarna. En vanlig textdiff flaggar var och en av dessa som en ändring, vilket döljer det du faktiskt bryr dig om. Den här guiden visar hur du får ett rent resultat.

Om du vill hoppa direkt till verktyget kan vår HTML-jämförelsesida låta dig klistra in två filer och se diff:en i din webbläsare — ingen installation krävs. Resten av artikeln förklarar vad du ska titta efter när du väl har resultatet.

Varför HTML-diff:ar producerar så mycket brus

HTML är inte ett radbaserat format. Ett stycke kan vara en lång rad eller sträcka sig över tio rader — båda är giltiga. De flesta editorer, kodformatare och CMS:er reformaterar HTML när de sparar, vilket innebär att en enskild ordändring kan kaskada till dussintals omformaterade rader. Diff:en ser dessa som ändrade rader, inte som "ett ord ändrat."

WHATWG HTML Living Standard specificerar hur webbläsare tolkar HTML, men säger inte hur det ska serialiseras tillbaka till text. Två verktyg kan producera strukturellt identisk HTML som ser helt olika ut som råtext.

Fyra saker svarar för det mesta av bruset:

  • Blanksteg mellan och inuti taggar
  • Attributordning (webbläsare kräver ingen specifik ordning)
  • HTML-entiteter kontra literala tecken
  • Void-elementsyntax (<br> kontra <br />)

Blanksteg: den största källan till falska positiva

I de flesta sammanhang kollapsar på varandra följande blanksteg i HTML till ett enda blanksteg när webbläsaren renderar det. Det innebär att dessa två kodstycken visas identiskt:

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

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

En vanlig textdiff markerar båda raderna som ändrade. De är inte ändrade i någon meningsfull mening. Innan du jämför, bestäm om blanksteg spelar roll för ditt ändamål. För e-postmallar eller PDF-renderare gör det det ibland. För de flesta webbsidor gör det det inte.

Den bästa lösningen är att köra båda filerna genom en formatare som Prettier med samma konfiguration innan du jämför. Det normaliserar indragningar, radlängd och blanksteg i ett steg. När båda filerna har samma formateringsstil flaggar en vanlig textdiff bara riktiga innehållsändringar.

Attributordning

HTML-specifikationen kräver inte att attribut visas i någon särskild ordning. <div id="main" class="container"> och <div class="container" id="main"> är samma element. Men en raddiff behandlar dem som olika rader. Det är särskilt vanligt när mallar genereras av olika verktyg eller när någon kör en auto-formatare som sorterar attribut alfabetiskt.

Enligt WHATWG:s tolkningsspecifikation är attribut på samma element per definition oordnade. En diff som rapporterar en attributomordning som en ändring är tekniskt korrekt men sällan användbar. Normalisera attributordningen i båda filerna innan du jämför om det skapar brus.

HTML-entiteter

&amp;, &lt;, &gt;, &nbsp;, numeriska referenser som &#8212; — det är alla sätt att koda tecken i HTML-källa. Två filer kan koda samma tecken olika och ändå rendera samma sida. En textdiff ser &amp; och & som olika strängar, även om båda producerar ett et-tecken i webbläsaren.

Om entitetsskillnader förorenar din diff, kör båda filerna genom en HTML-tolk som normaliserar entiteter innan du jämför. Webbläsarens egna DOMParser API är ett tillförlitligt sätt att göra detta i JavaScript: tolka båda strängarna, serialisera tillbaka med innerHTML och jämför resultatet.

Void-element

I HTML5 behöver void-element (element utan barn) inget avslutande snedstreck. <br>, <br/> och <br /> är alla giltiga och tolkas identiskt. Detsamma gäller <img>, <input>, <meta> och resten. Om den ena filen använder XHTML-stil självstängande snedstreck och den andra ren HTML5-syntax, flaggar en textdiff vart och ett av dessa element.

Den fullständiga listan över void-element på MDN täcker alla 14. En snabb sökning efter /> i ditt diff-resultat visar hur mycket av bruset som är självstängande syntax.

Ett genomarbetat exempel

Här är ett realistiskt före-och-efter för en webbplatshuvud. Tre saker ändrades: en CSS-klass lades till i headern, Home-länkens mål korrigerades och en Contact-länk lades till.

<!-- 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>

Klistra in båda i HTML-jämförelseverktyget så markerar diff:en exakt de tre raderna: header-klassattributet, Home-href:en och den nya ankartaggen. Inget brus, eftersom indragning och formatering är konsistenta mellan de två versionerna.

Vad som ändrades i exemplet ovan
Element Version 1 Version 2 Typ av ändring
<header> class="site-header" class="site-header sticky-top" Klass tillagd
Home-länk href="/home" href="/" Sökväg korrigerad
Contact-länk Finns ej <a href="/contact">Contact</a> Tillagd

När ska man normalisera innan man jämför

Inte varje HTML-jämförelse behöver normalisering. Om du jämför två filer du skrivit själv med samma editorinställningar räcker vanligtvis en vanlig textdiff. Normalisering lönar sig när:

  • En fil kom från en CMS-export och den andra från din editor
  • Ett byggverktyg formaterade om en fil men inte den andra
  • Du jämför minifierad HTML mot snygg utskriven HTML
  • Du granskar en HTML-e-postmall från en extern avsändare

W3C Markup Validation Service är användbar för att kontrollera att båda filerna tolkas korrekt innan du jämför dem. En fil med en trasig taggstruktur ger en vilseledande diff eftersom tolken återhämtar sig från fel på sitt eget sätt, och två tolkar kan återhämta sig olika.

Jämföra genererad HTML

Server-renderade ramverk (Angular, Next.js, Rails) bäddar ofta in tidsstämplar, nonces eller slumpmässiga identifierare i HTML-utmatningen. Två renderingar av samma sida ger olika diff på dessa rader även om innehållet är identiskt. Om du jämför genererad HTML, ta bort eller normalisera dessa fält innan du jämför.

Det underliggande diff-motorn på den här webbplatsen är Googles diff-match-patch (Apache 2.0), som arbetar med råtext. Det tolkar inte HTML, så det flaggar formateringsskillnader bredvid innehållsskillnader. Det är därför normalisering först spelar roll. För de flesta ändamål ger det att klistra in de två filerna direkt ett tillräckligt användbart resultat på några sekunder. Vårt XML-jämförelseverktyg är värt att prova om din HTML är välformad XHTML, eftersom XML-medveten diff hanterar namnrymder och attributordning korrekt.

Vanliga frågor

Varför visar min HTML-diff hundratals ändringar när jag bara ändrade en rad?
Det är nästan alltid en formateringsändring. Om din editor eller ett byggverktyg formaterade om filen (ändrade indragning, radbryt långa rader eller omordnade attribut) när du sparade, ser en vanlig textdiff varje omformaterad rad som en ändring. Kör båda filerna genom samma formatare först, jämför sedan. Den verkliga ändringen är den enda raden som är kvar.
Spelar attributordning roll i HTML?
Inte för webbläsaren. HTML Living Standard kräver inte att attribut visas i någon specifik ordning och webbläsare tolkar dem korrekt oavsett ordning. Vissa linters och formatare sorterar attribut alfabetiskt som en stilregel, vilket kan göra att två semantiskt identiska filer ser olika ut i en textdiff. Om attributordning skapar brus, normalisera båda filerna med samma formatare innan du jämför.
Vad är skillnaden mellan &amp;amp; och &amp; i HTML-källa?
Båda producerar ett et-tecken när webbläsaren renderar sidan. I HTML-källa är &amp; den entitetskodade formen och & det literala tecknet. Tekniskt sett bör & i attributvärden kodas som &amp; per specifikationen, men webbläsare accepterar båda. En textdiff behandlar dem som olika strängar. Om entitetskodning skapar brus, tolka båda filerna med ett bibliotek eller webbläsarens DOMParser och serialisera tillbaka innan du jämför.
Kan jag jämföra minifierad HTML mot snygg utskriven HTML?
Ja, men du bör snyggskriva den minifierade filen först. Att jämföra minifierad mot snygg utskriven ger ett resultat där nästan varje rad verkar ändrad, eftersom minifiering tar bort alla blanksteg som formataren lade till. Kör den minifierade filen genom Prettier eller en likvärdig formatare och jämför sedan. De meningsfulla ändringarna syns utan blanktegensbruset.
Hur jämför jag bara en del av en HTML-fil, som en specifik komponent?
Extrahera den relevanta delen från båda filerna och klistra bara in den i diff-verktyget. Om du till exempel granskar ändringar i en navigeringskomponent, kopiera bara <nav>-blocket från varje fil. Att jämföra hela dokumentet när du bara bryr dig om ett avsnitt lägger till brus från orelaterade delar av sidan.
Syns HTML-kommentarer i en diff?
Ja. En textbaserad diff inkluderar allt i filen, inklusive kommentarer. Om en version har ett kommentarsblock som den andra tog bort, eller om en utvecklare uppdaterade en kommentar, visar diff:en det. Det är oftast användbart: en borttagen kommentar signalerar ofta avsiktlig städning. Om du vill ignorera kommentarer, ta bort dem från båda filerna innan du jämför.

Redo att jämföra dina HTML-filer? Klistra in båda i det kostnadsfria HTML-jämförelseverktyget och se skillnaderna markerade sida vid sida — inget konto behövs.