O DOM, ou Document Object Model, é uma interface que permite linguagens de programação manipular o conteúdo e estrutura de uma aplicação web. No nosso caso, Javascript é a linguagem que se conecta ao DOM no navegador.
Em um nível mais básico, uma aplicação web consiste em um documento HTML. O navegador que usamos é um programa que interpreta HTML e CSS e renderiza os estilos, conteúdos e estrutura das páginas.
Além de converter a estrutura do HTML e CSS, o navegador cria uma representação conhecida como DOM. É essa estrutura que permite ao Javascript acessar os elementos da aplicação em forma de objetos.
Diferenças entre DOM e código fonte
Podemos imaginar que o código fonte da página é a mesma coisa do DOM. Porém, existem dos momentos em que o DOM pode ser diferente do código fonte:
- Quando o DOM é modificado via Javascript
- As alterações efetuadas em páginas através do Javascript não são refletidas no código fonte
- Quando o browser automaticamente corrige erros no código fonte
- O browser tenta corrigir automaticamente algumas falhas no código fonte, como por exemplo, a falta da tag
<tbody>
em uma tabela, a falta da tag<html>
, ou alguma tag que não tenha sido fechada
O DOM não é o que vemos no navegador
O que vemos na viewport é a render tree, uma combinação do DOM e do CSSOM. Como a render tree só se preocupa com o que será renderizado, elementos invisíveis são excluídos. Por exemplo,
display: none
O DOM não é o que vemos no DevTools
A diferença é muito pouca já que o DevTools é o mais próximo que temos do DOM no navegador, mas ainda assim, algumas informações adicionais não estão no DOM.
O melhor exemplo são os pseudo seletores de CSS, criados com
::before
e ::after
. Eles fazem parte da CSSOM, mas não do DOM.Isso acontece porque o DOM é formado apenas do HTML, não incluindo estilos.
Construindo o DOM
Antes que o navegador possa renderizar a página, é preciso construir o DOM e o CSSOM. É preciso garantir que esse processo entregue ambos HTML e CSS para o navegador da forma mais rápida possível.
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width,initial-scale=1" /> <link href="style.css" rel="stylesheet" /> <title>Critical Path</title> </head> <body> <p>Hello <span>web performance</span> students!</p> <div><img src="awesome-photo.jpg" /></div> </body> </html>
Como o browser processa essa página?
- Conversão: O navegador le os bytes do disco ou da rede, e os converte para caracteres individuais baseados no enconding do arquivo
- Tokenização: O navegador converte strings de caracteres em tokens disintos, como por exemplo
<html>
,<body>
e outras tags
- Conversão de tokens para nodes: Os tokens são convertidos em objetos, e tem suas propriedades e regras definidos
- Construção do DOM: Os objetos criados para representar as tags são vinculados em uma estrutura de árvore que também mantém a relação pai-filho definida no HTML. o
body
é pai de ump
e assim sucessivamente.
O resultado final desse processo é o DOM. Cada vez que o browser processa o HTML, todas as etapas acima são executadas.
CSSOM
Existe uma tag
link
no HTML de exemplo que referencia um CSS externo. Antecipando a necessidade desse recurso para renderizar a página, o navegador imediatamente dispara um request, que recebe o conteúdo:body { font-size: 16px; } p { font-weight: bold; } span { color: red; } p span { display: none; } img { float: right; }
Assim como com o HTML, o CSS precisa ser convertido em algo que o navegador entender, e assim, o mesmo processo é repetido
O CSS é convertido em bytes, tokens, nodes e finalmente vinculado a uma estrutura de árvore conhecida como CSSOM (CSS Object Model).
Por que o CSSOM tem estrutura de árvore? Quando o navegador está computando os estilos de qualquer objeto na página, começa pela regra mais geral aplicável para aquele node. Por exemplo, se é um filho da tag
body
, então os estilos do body
serão aplicados. E assim recursivamente os estilos mais específicos são computados. Em outras palavras, as regras de estilo são aplicadas em cascata.Cada navegador também possui seus estilos padrão aplicados a qualquer documento HTML. São chamados de user-agent stylesheets.