Sådan finder du forskelle mellem to HTML-filer

To HTML-filer kan blive vist identisk i en browser, men alligevel adskille sig på dusinvis af steder i kildekoden. Mellemrum rundt om tags, rækkefølgen af attributter, HTML-entiteter og selvlukkende syntaks er de sædvanlige syndere. En almindelig tekstdiff markerer hver eneste af dem som en ændring, hvilket skjuler det, du faktisk bekymrer dig om. Denne guide viser dig, hvordan du får et rent resultat.

Hvis du vil springe direkte til værktøjet, kan vores HTML-sammenligningsside lade dig indsætte to filer og se diff'en i din browser — ingen installation kræves. Resten af denne artikel forklarer, hvad du skal kigge efter, når du har outputtet.

Hvorfor HTML-diff'er producerer så meget støj

HTML er ikke et linjeorienteret format. Et afsnit kan være én lang linje eller strække sig over ti linjer — begge er gyldige. De fleste redaktører, kodeformatere og CMS'er reformaterer HTML, når de gemmer, hvilket betyder, at en enkelt ordændring kan kaskade til dusinvis af reformaterede linjer. Diff'en ser disse som ændrede linjer, ikke som "ét ord ændret."

WHATWG HTML Living Standard specificerer, hvordan browsere parser HTML, men siger ikke, hvordan det skal serialiseres tilbage til tekst. To værktøjer kan producere strukturelt identisk HTML, der som råtekst ser fuldstændig forskellig ud.

Fire ting tegner sig for det meste af støjen:

  • Mellemrum mellem og inde i tags
  • Attributrækkefølge (browsere kræver ingen bestemt rækkefølge)
  • HTML-entiteter kontra bogstavelige tegn
  • Void-elementsyntaks (<br> kontra <br />)

Mellemrum: den største kilde til falske positiver

I de fleste sammenhænge kollapser på hinanden følgende mellemrum i HTML til et enkelt mellemrum, når browseren gengiver det. Det betyder, at disse to kodestykker vises identisk:

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

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

En almindelig tekstdiff markerer begge linjer som ændrede. De er ikke ændret i nogen meningsfuld forstand. Inden du sammenligner, afgør om mellemrum betyder noget for dit brugstilfælde. For e-mailskabeloner eller PDF-renderere gør det det nogle gange. For de fleste websider gør det det ikke.

Den bedste løsning er at køre begge filer gennem en formater som Prettier med samme konfiguration inden diff'ing. Det normaliserer indrykning, linjelængde og mellemrum i ét trin. Når begge filer deler den samme formateringsstil, markerer en almindelig tekstdiff kun reelle indholdsændringer.

Attributrækkefølge

HTML-specifikationen kræver ikke, at attributter vises i nogen bestemt rækkefølge. <div id="main" class="container"> og <div class="container" id="main"> er det samme element. Men en linjediff behandler dem som forskellige linjer. Dette er særligt almindeligt, når skabeloner genereres af forskellige værktøjer, eller når nogen kører en auto-formater, der sorterer attributter alfabetisk.

Ifølge WHATWG-parserspecifikationen er attributter på det samme element pr. definition uordnede. En diff, der rapporterer en attributomordning som en ændring, er teknisk korrekt, men sjældent nyttig. Normaliser attributrækkefølgen i begge filer inden sammenligning, hvis dette forårsager støj.

HTML-entiteter

&amp;, &lt;, &gt;, &nbsp;, numeriske referencer som &#8212; — det er alle måder at kode tegn på i HTML-kildekode. To filer kan kode det samme tegn forskelligt og alligevel gengive den samme side. En tekstdiff ser &amp; og & som forskellige strenge, selvom begge producerer et ampersand-tegn i browseren.

Hvis entitetsforskelle forurener din diff, skal du køre begge filer gennem en HTML-parser, der normaliserer entiteter inden sammenligning. Browserens egne DOMParser API er en pålidelig måde at gøre dette på i JavaScript: parse begge strenge, serialiser tilbage med innerHTML, og sammenlign resultatet.

Void-elementer

I HTML5 behøver void-elementer (elementer uden børn) ikke en lukkende skråstreg. <br>, <br/> og <br /> er alle gyldige og parses identisk. Det samme gælder for <img>, <input>, <meta> og resten. Hvis den ene fil bruger XHTML-stil selvlukkende skråstreger og den anden bruger almindelig HTML5-syntaks, vil en tekstdiff markere hvert enkelt af disse elementer.

Den fulde liste over void-elementer på MDN dækker alle 14. En hurtig søgning efter /> i dit diff-output vil fortælle dig, hvor meget af støjen der er selvlukkende syntaks.

Et gennemarbejdet eksempel

Her er et realistisk før-og-efter for et webstedsoverskrift. Tre ting ændrede sig: en CSS-klasse blev tilføjet til headeren, Home-lænkens mål blev rettet, og et Contact-link blev tilføjet.

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

Indsæt begge i HTML-sammenligningsværktøjet, og diff'en fremhæver præcis de tre linjer: header-klasseattributten, Home-href'en og det nye ankertag. Ingen støj, fordi indrykning og formatering er konsistente mellem de to versioner.

Hvad der ændrede sig i eksemplet ovenfor
Element Version 1 Version 2 Type af ændring
<header> class="site-header" class="site-header sticky-top" Klasse tilføjet
Home-link href="/home" href="/" Sti rettet
Contact-link Ikke til stede <a href="/contact">Contact</a> Tilføjet

Hvornår skal du normalisere inden sammenligning

Ikke enhver HTML-sammenligning har brug for normalisering. Hvis du sammenligner to filer, du selv har skrevet med de samme editorindstillinger, er en almindelig tekstdiff normalt tilstrækkelig. Normalisering betaler sig, når:

  • Den ene fil kom fra en CMS-eksport og den anden fra din editor
  • Et byggeværktøj reformaterede den ene fil men ikke den anden
  • Du sammenligner minificeret HTML mod pænt formateret HTML
  • Du gennemgår en HTML-e-mailskabelon fra en ekstern afsender

W3C Markup Validation Service er nyttig til at kontrollere, at begge filer parses korrekt, inden du sammenligner dem. En fil med en defekt tagstruktur vil producere en vildledende diff, fordi parseren genopretter fra fejl på sin egen måde, og to parsere kan genoprette forskelligt.

Sammenligning af genereret HTML

Server-renderede frameworks (Angular, Next.js, Rails) indlejrer ofte tidsstempler, nonces eller tilfældige identifikatorer i HTML-outputtet. To renderinger af den samme side vil diff'e forskelligt på disse linjer, selvom indholdet er identisk. Hvis du sammenligner genereret HTML, skal du fjerne eller normalisere disse felter inden diff'ing.

Den underliggende diff-motor på dette websted er Googles diff-match-patch (Apache 2.0), som arbejder på råtekst. Den parser ikke HTML, så den vil markere formateringsforskelle ved siden af indholdsforskelle. Det er grunden til, at normalisering først er vigtig. I de fleste tilfælde giver det direkte indsætning af de to filer dog et tilstrækkeligt nyttigt resultat på få sekunder. Vores XML-sammenligningsværktøj er værd at prøve, hvis din HTML er velformet XHTML, da XML-bevidst diff'ing håndterer navnerum og attributrækkefølge korrekt.

Ofte stillede spørgsmål

Hvorfor viser min HTML-diff hundredvis af ændringer, når jeg kun ændrede én linje?
Det er næsten altid en formateringsændring. Hvis din editor eller et byggeværktøj reformaterede filen (ændrede indrykning, brød lange linjer eller ændrede rækkefølgen af attributter), da du gemte, ser en almindelig tekstdiff hver reformateret linje som en ændring. Kør begge filer gennem den samme formater først, og sammenlign derefter. Den reelle ændring vil være den eneste tilbageværende linje.
Betyder attributrækkefølgen noget i HTML?
Ikke for browseren. HTML Living Standard kræver ikke, at attributter vises i nogen bestemt rækkefølge, og browsere parser dem korrekt uanset rækkefølge. Nogle linters og formatere sorterer attributter alfabetisk som en stilregel, hvilket kan få to semantisk identiske filer til at se forskellige ud i en tekstdiff. Hvis attributrækkefølge forårsager støj, normaliser begge filer med den samme formater inden sammenligning.
Hvad er forskellen mellem &amp;amp; og &amp; i HTML-kildekode?
Begge producerer et og-tegn, når browseren gengiver siden. I HTML-kildekode er &amp; den entitetskodede form og & er det bogstavelige tegn. Teknisk set bør & i attributværdier kodes som &amp; ifølge specifikationen, men browsere accepterer begge. En tekstdiff behandler dem som forskellige strenge. Hvis entitetskodning skaber støj, skal du parse begge filer med et bibliotek eller browserens DOMParser og serialisere tilbage inden sammenligning.
Kan jeg sammenligne minificeret HTML med pænt formateret HTML?
Ja, men du bør pænt formatere den minificerede fil først. Diff'ing af minificeret mod pænt formateret producerer et resultat, hvor næsten hver linje ser ud til at være ændret, fordi minificering fjerner alle de mellemrum, formateren tilføjede. Kør den minificerede fil gennem Prettier eller en tilsvarende formater, og sammenlign derefter. De meningsfulde ændringer vil være synlige uden mellemrumsstøjen.
Hvordan sammenligner jeg kun en del af en HTML-fil, som en bestemt komponent?
Udtræk den relevante sektion fra begge filer og indsæt kun det i diff-værktøjet. For eksempel, hvis du gennemgår ændringer i en navigationskomponent, skal du kopiere blot <nav>-blokken fra hver fil. At sammenligne hele dokumentet, når du kun bekymrer dig om en sektion, tilføjer støj fra urelaterede dele af siden.
Vises HTML-kommentarer i en diff?
Ja. En tekstbaseret diff inkluderer alt i filen, herunder kommentarer. Hvis den ene version har en kommentarblok, som den anden fjernede, eller hvis en udvikler opdaterede en kommentar, vil diff'en vise det. Det er normalt nyttigt: en fjernet kommentar signalerer ofte bevidst oprydning. Hvis du vil ignorere kommentarer, skal du fjerne dem fra begge filer inden sammenligning.

Klar til at sammenligne dine HTML-filer? Indsæt begge i det gratis HTML-sammenligningsværktøj og se forskellene fremhævet side om side — ingen konto kræves.