Como identificar diferenças entre dois arquivos HTML
Dois arquivos HTML podem renderizar de forma idêntica em um navegador e ainda assim diferir em dezenas de lugares no código-fonte. Espaços em branco ao redor das tags, a ordem dos atributos, entidades HTML e a sintaxe de fechamento automático são os culpados habituais. Um diff de texto simples sinaliza cada um deles como uma mudança, o que enterra o que você realmente se importa. Este guia mostra como obter um resultado limpo.
Se você quiser ir direto à ferramenta, nossa página de comparação HTML permite colar dois arquivos e ver o diff no navegador, sem instalação necessária. O resto deste artigo explica o que procurar depois de ter o resultado.
Por que os diffs de HTML produzem tanto ruído
HTML não é um formato orientado a linhas. Um parágrafo pode ser uma linha longa ou distribuído por dez linhas, e ambos são válidos. A maioria dos editores, formatadores de código e CMSes reformatam o HTML ao salvar, o que significa que uma única mudança de palavra pode se propagar em dezenas de linhas reformatadas. O diff as vê como linhas alteradas, não como "uma palavra mudou."
O Padrão de Vida HTML da WHATWG especifica como os navegadores analisam o HTML, mas não diz como ele deve ser serializado de volta para texto. Duas ferramentas podem produzir HTML estruturalmente idêntico que não se parece em nada como texto bruto.
Quatro coisas explicam a maior parte do ruído:
- Espaços em branco entre e dentro das tags
- Ordem dos atributos (os navegadores não exigem uma ordem específica)
- Entidades HTML vs caracteres literais
- Sintaxe de elementos vazios (
<br>vs<br />)
Espaços em branco: a maior fonte de falsos positivos
Na maioria dos contextos, espaços em branco consecutivos em HTML são reduzidos a um único espaço quando o navegador os renderiza. Isso significa que estes dois trechos são exibidos de forma idêntica:
<!-- Version 1 -->
<p>Free text comparison tool.</p>
<!-- Version 2 -->
<p>
Free text comparison tool.
</p>
Um diff de texto simples marca ambas as linhas como alteradas. Elas não mudaram em nenhum sentido significativo. Antes de comparar, decida se os espaços em branco importam para o seu caso de uso. Para modelos de e-mail ou renderizadores de PDF, às vezes importam. Para a maioria das páginas web, não.
A melhor solução é passar os dois arquivos por um formatador como Prettier com a mesma configuração antes de fazer o diff. Isso normaliza a indentação, o comprimento de linha e o espaçamento em uma única etapa. Uma vez que os dois arquivos compartilham o mesmo estilo de formatação, um diff de texto simples só sinaliza mudanças de conteúdo genuínas.
Ordem dos atributos
A especificação HTML não exige que os atributos apareçam em nenhuma
ordem específica.
<div id="main" class="container"> e
<div class="container" id="main"> são o mesmo
elemento. Mas um diff de linhas os trata como linhas diferentes. Isso
é especialmente comum quando os templates são gerados por ferramentas
diferentes ou quando alguém executa um formatador automático que
ordena os atributos em ordem alfabética.
Segundo a especificação de análise da WHATWG, os atributos no mesmo elemento são desordenados por definição. Um diff que reporta uma reordenação de atributos como uma mudança é tecnicamente correto, mas raramente útil. Normalize a ordem dos atributos nos dois arquivos antes de comparar se isso estiver causando ruído.
Entidades HTML
&, <, >,
, referências numéricas como —
— todas são formas de codificar caracteres no código-fonte HTML. Dois
arquivos podem codificar o mesmo caractere de forma diferente e renderizar
a mesma página. Um diff de texto vê & e
& como strings diferentes, mesmo que ambas produzam um
ampersand no navegador.
Se as diferenças de entidades estiverem poluindo o seu diff, passe os
dois arquivos por um analisador HTML que normalize as entidades antes
de comparar. A própria
API DOMParser do navegador
é uma forma confiável de fazer isso em JavaScript: analise as duas
strings, serialize-as de volta com innerHTML e compare
o resultado.
Elementos vazios
Em HTML5, os elementos vazios (elementos sem filhos) não precisam de
uma barra de fechamento. <br>,
<br/> e <br /> são todos válidos
e todos analisados de forma idêntica. O mesmo vale para
<img>, <input>,
<meta> e o resto. Se um arquivo usar barras de
fechamento automático no estilo XHTML e o outro usar a sintaxe HTML5
simples, um diff de texto sinalizará cada um desses elementos.
A lista completa de
elementos vazios no MDN
cobre todos os 14. Uma busca rápida por /> no resultado
do diff dirá o quanto do ruído é sintaxe de fechamento automático.
Um exemplo real
Aqui está um antes e depois realista para o cabeçalho de um site. Três coisas mudaram: uma classe CSS foi adicionada ao cabeçalho, o destino do link de início foi corrigido e um link de contato foi adicionado.
<!-- 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>
Cole os dois na ferramenta de comparação HTML e o diff destaca exatamente essas três linhas: o atributo de classe do cabeçalho, o href de início e a nova tag de âncora. Sem ruído, porque a indentação e a formatação são consistentes entre as duas versões.
| Elemento | Versão 1 | Versão 2 | Tipo de mudança |
|---|---|---|---|
<header> |
class="site-header" |
class="site-header sticky-top" |
Classe adicionada |
| Link de início | href="/home" |
href="/" |
Caminho corrigido |
| Link de contato | Não presente | <a href="/contact">Contact</a> |
Adicionado |
Quando normalizar antes de comparar
Nem toda comparação de HTML precisa de normalização. Se você está comparando dois arquivos que você mesmo escreveu com as mesmas configurações de editor, um diff de texto simples geralmente é suficiente. A normalização compensa quando:
- Um arquivo veio de uma exportação de CMS e o outro do seu editor
- Uma ferramenta de build reformatou um arquivo mas não o outro
- Você está comparando HTML minificado com HTML formatado
- Você está revisando um modelo de e-mail HTML de um remetente externo
O Serviço de Validação de Marcação W3C é útil para verificar se os dois arquivos são analisados corretamente antes de compará-los. Um arquivo com uma estrutura de tags quebrada produzirá um diff enganoso porque o analisador se recupera de erros à sua própria maneira, e dois analisadores podem se recuperar de forma diferente.
Comparando HTML gerado
Frameworks de renderização no servidor (Angular, Next.js, Rails) muitas vezes incorporam timestamps, nonces ou identificadores aleatórios na saída HTML. Dois renderizamentos da mesma página terão diffs diferentes nessas linhas mesmo que o conteúdo seja idêntico. Se você está comparando HTML gerado, remova ou normalize esses campos antes de fazer o diff.
O mecanismo de diff subjacente neste site é o diff-match-patch do Google (Apache 2.0), que opera em texto bruto. Ele não analisa HTML, portanto sinalizará diferenças de formatação junto com diferenças de conteúdo. É por isso que normalizar primeiro importa. Para a maioria dos propósitos, porém, colar os dois arquivos diretamente fornece um resultado útil em poucos segundos. Nossa ferramenta de comparação XML também vale a pena tentar se o seu HTML for XHTML bem formado, pois o diff com suporte a XML lida corretamente com namespaces e ordem de atributos.
Perguntas frequentes
- Por que o meu diff de HTML mostra centenas de mudanças quando só alterei uma linha?
- Quase sempre é uma mudança de formatação. Se o seu editor ou uma ferramenta de build reformatou o arquivo (alterou a indentação, quebrou linhas longas ou reordenou atributos) ao salvar, um diff de texto simples vê cada linha reformatada como uma mudança. Passe os dois arquivos pelo mesmo formatador primeiro, depois compare. A mudança real será a única linha que sobrar.
- A ordem dos atributos é importante no HTML?
- Não para o navegador. O Padrão HTML não exige que os atributos apareçam em nenhuma ordem específica, e os navegadores os analisam corretamente independentemente. Alguns linters e formatadores ordenam os atributos em ordem alfabética como regra de estilo, o que pode fazer dois arquivos semanticamente idênticos parecerem diferentes em um diff de texto. Se a ordem dos atributos está causando ruído, normalize os dois arquivos com o mesmo formatador antes de comparar.
- Qual é a diferença entre &amp; e & no código-fonte HTML?
- Ambos produzem um caractere ampersand quando o navegador renderiza a página. No código-fonte HTML,
&é a forma codificada como entidade e&é o caractere literal. Tecnicamente,&em valores de atributo deveria ser codificado como&segundo a especificação, mas os navegadores aceitam os dois. Um diff de texto os trata como strings diferentes. Se a codificação de entidades está criando ruído, analise os dois arquivos com uma biblioteca ou o DOMParser do navegador e serialize antes de comparar. - Posso comparar HTML minificado com HTML formatado?
- Sim, mas você deve formatar o arquivo minificado primeiro. Comparar minificado com formatado produz um resultado onde quase toda linha parece alterada, porque a minificação remove todos os espaços em branco que o formatador adicionou. Passe o arquivo minificado pelo Prettier ou por um formatador equivalente, depois compare. As mudanças significativas serão visíveis sem o ruído dos espaços em branco.
- Como faço para comparar apenas parte de um arquivo HTML, como um componente específico?
- Extraia a seção relevante dos dois arquivos e cole apenas ela na ferramenta de diff. Por exemplo, se você está revisando mudanças em um componente de navegação, copie apenas o bloco
<nav>de cada arquivo. Comparar o documento inteiro quando você só se importa com uma seção adiciona ruído de partes não relacionadas da página. - Os comentários HTML aparecem em um diff?
- Sim. Um diff baseado em texto inclui tudo no arquivo, incluindo comentários. Se uma versão tem um bloco de comentários que a outra removeu, ou se um desenvolvedor atualizou um comentário, o diff vai mostrá-lo. Isso geralmente é útil: um comentário removido frequentemente indica uma limpeza intencional. Se você quiser ignorar comentários, remova-os dos dois arquivos antes de comparar.
Pronto para comparar seus arquivos HTML? Cole os dois na ferramenta gratuita de comparação HTML e veja as diferenças destacadas lado a lado, sem necessidade de conta.