Slik finner du forskjeller mellom to HTML-filer

To HTML-filer kan bli vist identisk i en nettleser, men likevel skille seg på dusinvis av steder i kildekoden. Mellomrom rundt tagger, rekkefølgen på attributter, HTML-entiteter og selvlukkende syntaks er de vanligste synderne. En vanlig tekstdiff markerer hver eneste av dem som en endring, noe som skjuler det du faktisk bryr deg om. Denne guiden viser deg hvordan du får et rent resultat.

Hvis du vil hoppe rett til verktøyet, kan vår HTML-sammenligningsside la deg lime inn to filer og se diff-en i nettleseren din — ingen installasjon kreves. Resten av denne artikkelen forklarer hva du skal se etter når du har utdataene.

Hvorfor HTML-diff-er produserer så mye støy

HTML er ikke et linjeorientert format. Et avsnitt kan være én lang linje eller strekke seg over ti linjer — begge er gyldige. De fleste redaktører, kodeformatere og CMS-er reformaterer HTML når de lagrer, noe som betyr at en enkelt ordendring kan kaskade til dusinvis av reformaterte linjer. Diff-en ser disse som endrede linjer, ikke som "ett ord endret."

WHATWG HTML Living Standard spesifiserer hvordan nettlesere parser HTML, men sier ikke hvordan det skal serialiseres tilbake til tekst. To verktøy kan produsere strukturelt identisk HTML som ser helt ulik ut som rå tekst.

Fire ting er ansvarlige for det meste av støyen:

  • Mellomrom mellom og inne i tagger
  • Attributtrekkefølge (nettlesere krever ingen bestemt rekkefølge)
  • HTML-entiteter kontra bokstavelige tegn
  • Void-elementsyntaks (<br> kontra <br />)

Mellomrom: den største kilden til falske positiver

I de fleste sammenhenger kollapser påfølgende mellomrom i HTML til ett enkelt mellomrom når nettleseren gjengir det. Det betyr at disse to kodesnuttene vises identisk:

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

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

En vanlig tekstdiff markerer begge linjene som endret. De er ikke endret i noen meningsfull forstand. Bestem deg før du sammenligner om mellomrom betyr noe for ditt brukstilfelle. For e-postmaler eller PDF-renderere gjør det det noen ganger. For de fleste nettsider gjør det det ikke.

Den beste løsningen er å kjøre begge filer gjennom en formater som Prettier med samme konfigurasjon før du sammenligner. Det normaliserer innrykk, linjelengde og mellomrom i ett steg. Når begge filene har samme formateringsstil, markerer en vanlig tekstdiff bare reelle innholdsendringer.

Attributtrekkefølge

HTML-spesifikasjonen krever ikke at attributter vises i noen bestemt rekkefølge. <div id="main" class="container"> og <div class="container" id="main"> er det samme elementet. Men en linjediff behandler dem som forskjellige linjer. Dette er spesielt vanlig når maler genereres av forskjellige verktøy eller når noen kjører en auto-formater som sorterer attributter alfabetisk.

Ifølge WHATWG-parserspesifikasjonen er attributter på det samme elementet per definisjon uordnede. En diff som rapporterer en attributtomsortering som en endring er teknisk korrekt, men sjelden nyttig. Normaliser attributtrekkefølgen i begge filer før sammenligning hvis dette skaper støy.

HTML-entiteter

&amp;, &lt;, &gt;, &nbsp;, numeriske referanser som &#8212; — dette er alle måter å kode tegn på i HTML-kildekode. To filer kan kode det samme tegnet forskjellig og likevel gjengi den samme siden. En tekstdiff ser &amp; og & som forskjellige strenger, selv om begge produserer et og-tegn i nettleseren.

Hvis entitetsforskjeller forurenser diff-en din, kjør begge filer gjennom en HTML-parser som normaliserer entiteter før sammenligning. Nettleserens egne DOMParser API er en pålitelig måte å gjøre dette på i JavaScript: parse begge strenger, serialiser tilbake med innerHTML, og sammenlign resultatet.

Void-elementer

I HTML5 trenger void-elementer (elementer uten barn) ikke en avsluttende skråstrek. <br>, <br/> og <br /> er alle gyldige og parses identisk. Det samme gjelder for <img>, <input>, <meta> og resten. Hvis den ene filen bruker XHTML-stil selvlukkende skråstreker og den andre bruker vanlig HTML5-syntaks, vil en tekstdiff markere hvert eneste av disse elementene.

Den fullstendige listen over void-elementer på MDN dekker alle 14. Et raskt søk etter /> i diff-utdataene dine vil fortelle deg hvor mye av støyen som er selvlukkende syntaks.

Et gjennomarbeidet eksempel

Her er et realistisk før-og-etter for en nettstedshode. Tre ting endret seg: en CSS-klasse ble lagt til i headeren, Home-lenkens mål ble rettet, og en Contact-lenke ble lagt til.

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

Lim inn begge i HTML-sammenligningsverktøyet, og diff-en fremhever nøyaktig de tre linjene: header-klasseattributtet, Home-href-en og den nye ankertagen. Ingen støy, fordi innrykk og formatering er konsistente mellom de to versjonene.

Hva som endret seg i eksemplet ovenfor
Element Versjon 1 Versjon 2 Type endring
<header> class="site-header" class="site-header sticky-top" Klasse lagt til
Home-lenke href="/home" href="/" Sti rettet
Contact-lenke Ikke til stede <a href="/contact">Contact</a> Lagt til

Når du bør normalisere før sammenligning

Ikke enhver HTML-sammenligning trenger normalisering. Hvis du sammenligner to filer du selv har skrevet med de samme editorinnstillingene, er en vanlig tekstdiff vanligvis tilstrekkelig. Normalisering lønner seg når:

  • Den ene filen kom fra en CMS-eksport og den andre fra editoren din
  • Et byggverktøy reformaterte den ene filen, men ikke den andre
  • Du sammenligner minifisert HTML mot pent formatert HTML
  • Du gjennomgår en HTML-e-postmal fra en ekstern avsender

W3C Markup Validation Service er nyttig for å kontrollere at begge filer parses korrekt før du sammenligner dem. En fil med en ødelagt tagstruktur vil produsere en villedende diff fordi parseren gjenoppretter fra feil på sin egen måte, og to parsere kan gjenopprette forskjellig.

Sammenligning av generert HTML

Server-renderte rammeverk (Angular, Next.js, Rails) innebygger ofte tidsstempler, nonces eller tilfeldige identifikatorer i HTML-utdataene. To renderinger av den samme siden vil diff-e forskjellig på disse linjene, selv om innholdet er identisk. Hvis du sammenligner generert HTML, fjern eller normaliser disse feltene før du sammenligner.

Den underliggende diff-motoren på dette nettstedet er Googles diff-match-patch (Apache 2.0), som arbeider på rå tekst. Den parser ikke HTML, så den vil markere formateringsforskjeller ved siden av innholdsforskjeller. Det er grunnen til at normalisering først er viktig. For de fleste formål gir det å lime inn de to filene direkte imidlertid et tilstrekkelig nyttig resultat på noen sekunder. Vårt XML-sammenligningsverktøy er verdt å prøve hvis HTML-en din er velformet XHTML, siden XML-bevisst diff-ing håndterer navnerom og attributtrekkefølge korrekt.

Ofte stilte spørsmål

Hvorfor viser HTML-diff-en min hundrevis av endringer når jeg bare endret én linje?
Det er nesten alltid en formateringsendring. Hvis editoren din eller et byggverktøy reformaterte filen (endret innrykk, brøt lange linjer eller omordnet attributter) da du lagret, ser en vanlig tekstdiff hver reformatert linje som en endring. Kjør begge filer gjennom den samme formateren først, og sammenlign deretter. Den reelle endringen vil være den eneste gjenværende linjen.
Betyr attributtrekkefølge noe i HTML?
Ikke for nettleseren. HTML Living Standard krever ikke at attributter vises i noen bestemt rekkefølge, og nettlesere parser dem korrekt uavhengig av rekkefølge. Noen lintere og formatere sorterer attributter alfabetisk som en stilregel, noe som kan gjøre to semantisk identiske filer til å se forskjellige ut i en tekstdiff. Hvis attributtrekkefølge skaper støy, normaliser begge filer med den samme formateren før sammenligning.
Hva er forskjellen mellom &amp;amp; og &amp; i HTML-kildekode?
Begge produserer et og-tegn når nettleseren gjengir siden. I HTML-kildekode er &amp; den entitetskodede formen og & er det bokstavelige tegnet. Teknisk sett bør & i attributtverdier kodes som &amp; per spesifikasjonen, men nettlesere aksepterer begge. En tekstdiff behandler dem som forskjellige strenger. Hvis entitetskoding skaper støy, parse begge filer med et bibliotek eller nettleserens DOMParser og serialiser tilbake før sammenligning.
Kan jeg sammenligne minifisert HTML mot pent formatert HTML?
Ja, men du bør pent formatere den minifiserte filen først. Diff-ing av minifisert mot pent formatert produserer et resultat der nesten hver linje ser ut til å være endret, fordi minifisering fjerner alle mellomrommene formateren la til. Kjør den minifiserte filen gjennom Prettier eller en tilsvarende formater, og sammenlign deretter. De meningsfulle endringene vil være synlige uten mellomromsstøyen.
Hvordan sammenligner jeg bare en del av en HTML-fil, for eksempel en bestemt komponent?
Trekk ut den relevante seksjonen fra begge filer og lim bare det inn i diff-verktøyet. For eksempel, hvis du gjennomgår endringer i en navigasjonskomponent, kopier bare <nav>-blokken fra hver fil. Å sammenligne hele dokumentet når du bare bryr deg om én seksjon legger til støy fra urelaterte deler av siden.
Vises HTML-kommentarer i en diff?
Ja. En tekstbasert diff inkluderer alt i filen, inkludert kommentarer. Hvis den ene versjonen har en kommentarblokk som den andre fjernet, eller hvis en utvikler oppdaterte en kommentar, vil diff-en vise det. Det er vanligvis nyttig: en fjernet kommentar signalerer ofte bevisst opprydding. Hvis du vil ignorere kommentarer, fjern dem fra begge filer før sammenligning.

Klar til å sammenligne HTML-filene dine? Lim inn begge i det gratis HTML-sammenligningsverktøyet og se forskjellene fremhevet side om side — ingen konto kreves.