¿Cómo funcionan los navegadores?


Este artículo es un resumen del manual "Cómo funcionan los navegadores: Lo que hay detrás de los navegadores web actuales" escrito por Tali Garsiel y Paul Irish.


¿Cómo funcionan los navegadores?

 URI (Uniform resource identifier), URL (Uniform resource location), URN (Uniform resource name).

Para acceder a una página web necesitamos su ubicación. La URI es el identificador de un archivo alojado en algún sitio de internet, esta identificación contiene un nombre y una localización.

En algunos casos solo se utiliza el nombre o la localización, para esto y evitar confusiones a la hora de acceder a un archivo con su identificación (URI) se crearon por separado la localización (URL) y nombre (URN) del archivo.

Entonces, URI = Identificador del archivo, URL = Localización del archivo, URN = Nombre del archivo.

Desde que dos archivos pueden tener el mismo nombre la URN no es tan útil, por esto en la mayoría de los casos se usa la URL.

Un poco más sobre la URL…

Para poder pedir recursos a un servidor web, el protocolo HTTP usa la URL para identificar la localización de la página web en el internet.

Las URL tienen dos campos requeridos: el protocolo y el dominio. Además, tiene algunos opcionales como el puerto, el path, queries y fragmentos.

http://www.example.com/people?fn=Link/#Place

Protocolo

Dominio

Path

Query

Fragmento


INTRODUCCIÓN


FUNCIÓN DE UN NAVEGADOR

La función principal del navegador es pedir al servidor web la URI buscada por el cliente, renderizar la página bien sea un archivo HTML, PDF, imagen u otro tipo para posteriormente mostrarla en pantalla.

La manera en cómo se interpretan y muestran los archivos HTML viene por medio del consorcio WC3 que determina las especificaciones HTML, CSS y los estándares de internet. Los navegadores cumplen en mayor o menor medida estas especificaciones, algunos añadiendo funciones únicas como el administrador de descargas de Firefox.

 Componentes principales

1.       Interfaz de usuario: Incluye en general toda la parte visible para el usuario.

2.       Motor de búsqueda: Coordina acciones entre la interfaz y el motor de renderización.

3.       Motor de renderización: Es responsable de analizar el contenido solicitado por el cliente como HTML y CSS para mostrarlo luego en pantalla.

4.       Red: Es el responsable de las llamadas que corresponden a la red, como son las peticiones HTTP.

5.       Servidor de la interfaz: Permite presentar widgets básicos como ventanas.

6.       Intérprete de JavaScript: Permite interpretar y ejecutar código JavaScript.

7.       Almacenamiento de datos: Es una ligera, pero completa base de datos que almacenan los navegadores en el dispositivo como son las cookies.




MOTOR DE RENDERIZACIÓN

 Es capaz de analizar el contenido HTML y XML, pero necesita extensiones para poder interpretar PDF u otros.

Los navegadores populares están basados en dos motores de renderización, Firefox en Gecko propio de Mozilla y WebKit de código abierto presente en Chrome.

Flujo:

1.       Empieza recibiendo el contenido solicitado desde la capa de red (Este contenido llega por partes generalmente de 8.000 bytes)

2.       Analiza y convierte las etiquetas del HTML en nodos DOM y crea un “árbol de contenido”

3.       Analiza los estilos CSS junto a instrucciones visuales del HTML y crea otro “árbol de renderización”

4.       El árbol de renderización contiene rectángulos con atributos visuales como el color y dimensiones y estos están organizados en el orden que deben aparecer en pantalla

5.       Una vez creado el árbol de renderización, se inicia una etapa de “diseño” donde se le asignará a cada elemento las coordenadas donde deben ir.

6.       Ahora una etapa de “pintura” en donde se recorrerán los elementos y se pintarán.

7.       Este proceso es gradual, por tanto, el motor de renderización no esperará a que llegue todo el contenido de la red para empezar a analizar y mostrar en pantalla por partes. Esto se hace con intención de mostrar lo más pronto en pantalla el contenido y mejorar la experiencia de usuario


Flujo principal de WebKit

El flujo entre WebKit y Gecko de Mozilla es básicamente el mismo, aunque con diferencias en la terminología. Analizar un archivo significa convertir el código HTML en una estructura que tenga sentido, el resultado es un árbol de nodos que representa la estructura del archivo. Generalmente, se le denomina “árbol de análisis”.

Ejemplo: el árbol de análisis de la expresión 2 + 3 – 1 podría ser este:


Nodo árbol expresión matemática

ANÁLISIS

El análisis del documento se rige por unas reglas gramaticales libres de contexto, estas reglas son el lenguaje o formato en el que está escrito el documento. Todos los formatos deben tener una determinada gramática: un vocabulario y reglas de sintaxis.

Este analizador puede descomponerse entonces, en dos partes: análisis léxico (vocabulario) y análisis sintáctico (sintaxis). 

Análisis léxico: Es el encargado de descomponer los datos de entrada en tokens, los tokens son el vocabulario del lenguaje y estos tokens son bloques de construcción válidos. En un lenguaje convencional equivaldría a todas las palabras de un diccionario.

Análisis sintáctico: Es la aplicación de las reglas sintácticas del lenguaje, es decir, comprueba que el documento este escrito gramaticalmente correctamente. Es capaz de ignorar caracteres irrelevantes como espacios en blanco y saltos de línea.

También podemos añadir otro tipo de análisis, el semántico que comprueba que no haya inconsistencias o contradicciones, por ejemplo: Jorge es un soltero casado, pero normalmente los analizadores se dividen el trabajo entre un analizador léxico responsable de descomponer los datos a tokens y el analizador normal que es responsable de tras comprobar las reglas sintácticas del lenguaje crear el árbol de análisis.


Del documento original al árbol de análisis

El análisis es un proceso iterativo, este irá de la siguiente manera:

1.       El analizador pedirá al analizador léxico un token

2.       Buscará una coincidencia del token con las reglas de sintaxis

3.       Si encuentra una regla añadirá un nodo correspondiente al token al árbol de análisis

4.       Si no encuentra la regla, almacenará al token internamente y pedirá otro token

5.       Buscará entonces reglas correspondientes a los tokens almacenados internamente, si no hay ninguna regla lanzará una excepción, es decir, invalidará el documento por contener errores de sintaxis.

Traducción: Muchas veces el árbol de análisis no es el producto final. El árbol de análisis pasa por un proceso de traducción a otro formato, como pasa en los compiladores que el árbol de análisis pasa por una traducción a código máquina.


Flujo de compilación

Ejemplo con 2 + 3 – 1

 

Vocabulario: El lenguaje puede incluir números enteros, el signo positivo (+) y negativo (-)

 

Reglas de sintaxis:

1.        Los bloques de construcción serán términos, expresiones y operaciones

2.       Puede incluir cualquier cantidad de expresiones.

3.       Una expresión es igual a un término seguido de una operación y de otro término

4.       Una operación es un token de suma o resta

5.       Un término es un token de número entero o una expresión

Al analizar la entrada 2 + 3 – 1

-          La primera coincidencia que tenemos está en la regla 5, con el término “2”

-          La segunda está en la expresión “2 + 3” que está en la regla 3

-          La siguiente será la expresión total que estará al final de analizar toda la entrada “2 + 3 – 1”

Un error que invalidaría la ejecución sería la expresión “2 + +” 


ANALIZADOR HTML

Este se encarga de analizar las etiquetas HTML y organizarlas en un árbol de análisis; la sintaxis y el vocabulario son especificados por W3C

El lenguaje HTML no se puede analizar fácilmente por analizadores convencionales, puesto a que HTML es un lenguaje “permisivo”, ósea, tiene una sintaxis flexible. Existe un formato formal para definir al lenguaje HTML: DTD, pero no es una gramática libre de contexto.

DOM


El árbol de salida o árbol de análisis está formado por elementos DOM y nodos de atributo. DOM son las siglas de “Document Object Model”.

Nodos: Es cualquier etiqueta presente en el cuerpo, como un párrafo o la etiqueta <body>
Ejemplo del árbol de análisis con el marcado de HTML:

<html>

                <body>

                <p> Hello World </p>

                <div> <img src=”example.png” /> </div>

</body>

</html>

Árbol de contenido (DOM) del ejemplo

 El algoritmo del analizador personalizado de HTML tiene bastante complejidad, por los estados en los que incurre la ejecución. Eventos como document.write cambian los tokens del documento, por tanto en una forma simplificada lo que hace este algoritmo es abrir un estado cada que encuentra un carácter “<”, luego identifica el nombre de la etiqueta “div”, analiza lo que haya dentro de la etiqueta y finalmente cierra el estado cuando encuentra “/>”.

Luego pasa a la construcción del árbol usando un algoritmo, lo primero que sucede es que se crea un objeto “Document” que es la raíz de todo y donde se añadirán los elementos. Este constructor (algoritmo) añadirá cada nodo que entrega el token. Algunos elementos se mantendrán activos para corregir errores de sintaxis.

Al finalizar este análisis, el navegador marcará el documento como interactivo y empezará a analizar las secuencias de comandos “aplazados”, es decir, aquellas secuencias que deben ejecutarse luego de haber analizado el documento. Una vez hecho esto el navegador establecerá el estado del documento como “completado” y se activará un evento de “carga”.

Hay una serie de errores convencionales que se infringen en los documentos, los navegadores desarrollaron a través de los años una tolerancia a estos errores, corrigiéndolos de la mejor manera posible.

Un ejemplo es abrir una etiqueta que no existe “<mytag>hi</mytag>”, cerrar desde el comienzo una etiqueta “</br>” etc.


ANÁLISIS CSS

A diferencia de HTML, CSS tiene una gramática libre de contexto y puede analizarse con los tipos anteriormente dichos: análisis léxico y sintáctico.

Escribir manualmente un analizador es una tarea compleja, por esto existen generadores de analizadores que crean análisis léxico y sintáctico automáticamente. WebKit utiliza los generadores de analizadores Flex y Bison mientras que Firefox utiliza uno escrito manualmente; en ambos casos los archivos CSS se analizan y se convierten en objetos “StyleSheet”, cada uno contiene reglas gramáticas de CSS.

Análisis de hojas de estilo (CSS)


SECUENCIA DE COMANDOS (JavaScript)

El modelo de la web es sincrónico

1.       Se espera que los comandos sean analizados para que se ejecuten inmediatamente el analizador llegué a la etiqueta <script>

2.       El análisis del documento será detenido hasta que la secuencia de comandos sea ejecutada.

3.       La secuencia de comandos es externa, por lo que es necesario recuperar el archivo de la red. También de forma síncrono, ósea, se detiene el análisis hasta recuperar el archivo.

Este modelo fue utilizado durante muchos años, ahora los desarrolladores pueden marcar la secuencia de comando como “aplazada”. Así, no se detiene el análisis del documento y la secuencia se ejecuta una vez se haya completado el análisis.

HTML5, además, añade una opción que permite marcar la secuencia de comandos como ejecución asíncrona para que se analice y ejecute en un subproceso distinto.

ANALISIS ESPECULATIVO: Este análisis se hace en paralelo al análisis principal, se encarga de cargar y analizar los recursos externos en subprocesos para mejorar la velocidad de carga, no modifica el DOM.

Las hojas de estilo (CSS), deben analizarse primero a la secuencia de comandos (JavaScript). Esto es por qué en ocasiones, los comandos hacen solicitud de información de estilos durante la fase de análisis del documento. Esto incurre en errores si no se ha completado la carga o análisis de los estilos, por esto Firefox bloquea la secuencia de comandos si todavía se están cargando los estilos mientras que WebKit bloquea comandos que hagan alusión a propiedades de estilo.


ÁRBOL DE RENDERIZACIÓN

A la vez que se construye el árbol DOM, el navegador construye este árbol de renderización. Este árbol esta formado por los elementos visuales en el orden que se esperan mostrar, su propósito es representar el contenido en el orden correcto. Los elementos de este árbol pueden llamarse “frames” (En Firefox) o “render” (En WebKit).

ÁRBOL DOM Y ÁRBOL DE RENDERIZACIÓN

Los render corresponden a elementos DOM, pero no uno a uno. Elementos no visuales como <head> o con atributo de visualización “none” no son insertados en el árbol de renderización.

Algunos elementos DOM corresponden a múltiples render por su complejidad, como lo son la etiqueta <select> que dispone de tres render: uno para el área de visualización, otro para la lista desplegable y otro para el botón.

Al procesar las etiquetas <html> y <body>, se construye la raíz del árbol de renderización este es el “bloque contenedor” donde estarán todos los otros bloques (elementos) insertados de los nodos DOM. 


DISEÑO

Cuando el render se crea y se añade al árbol, no tiene posición ni tamaño. El cálculo de esto valores se conoce como diseño o reflujo, cada render tiene un método de “diseño”.

Este proceso conlleva cálculos geométricos que se realizan una sola vez, pues los elementos posteriores no suelen influir en la geométrica de los anteriores, por lo que el diseño puede aplicarse en un marco de coordenadas que van de izquierda a derecha y de arriba a abajo en el documento. Aunque hay excepciones, como las tablas HTML que conllevan más de un cálculo.

Para no iniciar un proceso de diseño completo con cada pequeña modificación, el navegador utiliza un sistema de modificación (dirty bit). Cuando se añade o modifica un render se marca con un indicador “dirty”, lo que significa que se debe someter a un proceso de diseño.

Cuando se activa un proceso de diseño por un cambio de tamaño o posición del render, el tamaño se toma de una caché en lugar de recalcularse. En cambios locales, como la inserción de texto en campos de texto, el proceso de diseño solo modificará un subárbol y no modifica a los elementos que lo rodean, de lo contrario cada tecla activaría un diseño completo del documento.


PINTURA

En esta fase se recorre el árbol de renderización y se activa el método “pintura” del render para que muestre su contenido en pantalla. Igualmente, que en el diseño hay un proceso global que conlleva la “pintura” de la totalidad del árbol y otro proceso incremental, en el que los render se modifican de una forma que no afecte todo el árbol.

 

Los navegadores intentan ejecutar la menor cantidad de acciones posibles cuando se produce un cambio, por tanto, si hay cambios en el color de un elemento se pintará solamente ese elemento. Si hay cambios en la posición, se diseña y pinta nuevamente solo ese elemento y sus secundarios. Si se añade un nuevo nodo DOM se activará un proceso de diseño y pintura de ese nodo. Y en cambios de mayor importancia como el cambio de fuente se invalidarán las cachés para luego activarse un proceso de pintura y diseño del árbol completo.

 

 

SUBPROCESOS DEL MOTOR DE RENDERIZACIÓN

El motor de renderización ocurre generalmente en un único subproceso. Casi todas las operaciones, excepto las de red se generan en un único subproceso. En Firefox y Safari es el subproceso principal del navegador, mientras que en Chrome es el subproceso principal del proceso de pestaña.

Los procesos de red se pueden realizan paralelamente en varios subprocesos, pero es limitado normalmente de dos a seis conexiones.

El subproceso principal es un bucle infinito que mantiene el proceso activo. Espera eventos como diseño y pintura para procesar.

Publicar un comentario

Artículo Anterior Artículo Siguiente