Fecha de publicación: 31 de marzo de 2014
Para que el navegador pueda representar la página, debe construir los árboles del DOM y el CSSOM. En consecuencia, debemos asegurarnos de proporcionar lenguaje de marcado HTML y CSS al navegador lo más rápido posible.
Resumen
- Bytes → caracteres → tokens → nodos → modelo de objetos.
- El lenguaje de marcado HTML se transforma en un Document Object Model (DOM) y el lenguaje de marcado CSS se transforma en un CSS Object Model (CSSOM).
- DOM y CSSOM son estructuras de datos independientes.
- El panel Rendimiento de Chrome DevTools nos permite capturar e inspeccionar los costos de construcción y procesamiento del DOM y CSSOM.
Modelo de objetos del documento (DOM)
<!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>
Comienza con el caso más sencillo: una página HTML estándar, con un poco de texto y una sola imagen. ¿Cómo el navegador procesa esta página?
- Conversión: El navegador lee los bytes sin procesar del HTML del disco o de la red y los traduce en caracteres individuales según la codificación especificada del archivo (por ejemplo, UTF-8).
- Tokenización: El navegador convierte cadenas de caracteres en tokens distintos, como se especifica en el estándar HTML5 del W3C, por ejemplo,
<html>
,<body>
, y otras cadenas entre paréntesis angulares. Cada token tiene un significado especial y un conjunto de reglas propio. - Lexicalización: Los tokens emitidos se convierten en “objetos” que definen sus propiedades y reglas.
- Construcción del DOM: Por último, como el lenguaje de marcado HTML define relaciones entre diferentes etiquetas (algunas etiquetas se contienen dentro de otras), los objetos creados se vinculan en una estructura de datos de árbol que también captura las relaciones de elementos superiores y secundarios definidas en el lenguaje de marcado original: el objeto HTML es superior del objeto body, el body es superior del objeto paragraph, y así sucesivamente, hasta que se compila toda la representación del documento.
El resultado final de todo este proceso es el Document Object Model (DOM) de nuestra página simple, que el navegador usa para todos los demás procesamientos de la página.
Cada vez que el navegador procesa el lenguaje de marcado HTML, realiza todos los pasos que se definieron anteriormente: convertir bytes en caracteres, identificar tokens, convertir tokens en nodos y compilar el árbol del DOM. Todo este proceso puede tardar un poco, especialmente si hay mucho HTML para procesar.
Si abres Chrome DevTools y registras una línea de tiempo mientras se carga la página, puedes ver el tiempo necesario para este paso. En el ejemplo anterior, la conversión de un fragmento de HTML en un árbol del DOM tardó ~5 ms. En el caso de una página más grande, este proceso puede durar mucho más. Cuando creas animaciones fluidas, esto puede convertirse en un cuello de botella si el navegador debe procesar grandes cantidades de HTML.
El árbol del DOM captura las propiedades y relaciones del lenguaje de marcado del documento, pero no muestra indicios sobre el aspecto que debe tener el elemento al representarse. Esa es la responsabilidad del CSSOM.
CSS Object Model (CSSOM)
Mientras el navegador construía el DOM de nuestra página básica, encontró un elemento <link>
en el <head>
del documento que hacía referencia a una hoja de estilo CSS externa: style.css
. Previniendo que necesita este recurso para representar la página, envía de inmediato una solicitud de este recurso, que regresa con el siguiente contenido:
body {
font-size: 16px;
}
p {
font-weight: bold;
}
span {
color: red;
}
p span {
display: none;
}
img {
float: right;
}
Podríamos haber declarado nuestros estilos directamente en el lenguaje de marcado HTML (integrado), pero mantener la independencia de nuestro lenguaje de marcado CSS respecto del HTML nos permite abordar el contenido y el diseño como dos temas independientes: los diseñadores pueden trabajar en CSS, los programadores en HTML, etc.
Al igual que con HTML, debemos convertir las reglas de CSS recibidas en algo que el navegador comprenda y con lo que pueda trabajar. Por lo tanto, repetimos el proceso de HTML, pero para CSS en lugar de HTML:
Los bytes del CSS se convierten en caracteres, luego en tokens y nodos y, por último, se vinculan en una estructura de árbol conocida como “CSS Object Model” (CSSOM):
¿Por qué el CSSOM tiene una estructura de árbol? Cuando se calcula el conjunto final de estilos para cualquier objeto de la página, el navegador comienza con la regla más general aplicable a ese nodo (por ejemplo, si es un elemento secundario de un elemento de cuerpo, se aplican todos los estilos de cuerpo) y, luego, refina de forma recursiva los estilos calculados aplicando reglas más específicas; es decir, las reglas “se aplican en cascada”.
Para ser más concretos, considera el árbol del CSSOM que se describió anteriormente. El texto que se encuentra dentro de la etiqueta <span>
que se coloca dentro del elemento body tiene un tamaño de fuente de 16 píxeles y es de color rojo; la directiva font-size
se encuentra en una jerarquía de órdenes descendentes desde body
hasta span
. Sin embargo, si un span
es un elemento secundario de una etiqueta de párrafo (p
), no se mostrará su contenido.
Ten en cuenta también que el árbol descrito anteriormente no es el árbol completo del CSSOM y solo muestra los estilos que decidimos anular en nuestra hoja de estilos. Cada navegador proporciona un conjunto predeterminado de estilos, también conocidos como “estilos de usuario-agente” (lo que vemos cuando no proporcionamos los nuestros), y nuestros estilos simplemente anulan a los predeterminados.
Para saber cuánto tiempo tarda el procesamiento de CSS, puedes registrar una línea de tiempo en DevTools y buscar el evento "Recalculate Style": a diferencia del análisis del DOM, la línea de tiempo no muestra una entrada "Parse CSS" independiente y, en su lugar, captura el análisis y la construcción del árbol del CSSOM, además del cálculo recursivo de los estilos computados en este evento.
Nuestra hoja de estilo trivial tarda alrededor de 0.6 ms en procesarse y afecta a ocho elementos de la página; no es mucho, pero una vez más, no es gratis. Sin embargo, ¿de dónde provienen los ocho elementos? El CSSOM y el DOM son estructuras de datos independientes. Resulta que el navegador está escondiendo un paso importante. A continuación, se analizará el árbol de renderización, que vincula el DOM y el CSSOM.