Cómo funciona el navegador web moderno (parte 2)

Mariko Kosaka

Qué sucede en la navegación

Esta es la segunda parte de una serie de blogs de 4 partes que analiza el funcionamiento interno de Chrome. En la entrada anterior, vimos cómo los diferentes procesos y subprocesos manejan diferentes partes de un navegador. En esta publicación, profundizamos sobre cómo se comunica cada proceso y hilo para mostrar un sitio web.

Veamos un caso de uso simple de la navegación web: escribes una URL en un navegador y este recupera datos de Internet y muestra una página. En esta publicación, nos enfocaremos en la parte en la que un usuario solicita un sitio y el navegador se prepara para procesar una página, también conocida como navegación.

Comienza con un proceso de navegación.

Procesos del navegador
Figura 1: IU del navegador en la parte superior; diagrama del proceso del navegador con IU, red y subproceso de almacenamiento en la parte inferior

Como cubrimos en la parte 1: CPU, GPU, memoria y arquitectura de varios procesos, el proceso del navegador controla todo fuera de una pestaña. El proceso del navegador tiene subprocesos, como el subproceso de IU, que dibuja botones y campos de entrada del navegador, el subproceso de red que se ocupa de la pila de red para recibir datos de Internet, el subproceso de almacenamiento que controla el acceso a los archivos y mucho más. Cuando escribes una URL en la barra de direcciones, el subproceso de IU del proceso del navegador controla la entrada.

Navegación sencilla

Paso 1: Controla las entradas

Cuando un usuario comienza a escribir en la barra de direcciones, lo primero que pregunta el subproceso de IU es "¿Es una búsqueda o una URL?". En Chrome, la barra de direcciones también es un campo de entrada de búsqueda, por lo que el subproceso de IU debe analizar y decidir si te enviará a un motor de búsqueda o al sitio que solicitaste.

Cómo controlar las entradas del usuario
Figura 1: Subproceso de IU que pregunta si la entrada es una búsqueda o una URL

Paso 2: Inicia la navegación

Cuando un usuario presiona Intro, el subproceso de IU inicia una llamada de red para obtener el contenido del sitio. Se muestra el ícono giratorio de carga en la esquina de una pestaña, y el subproceso de red pasa por los protocolos apropiados, como la búsqueda de DNS y el establecimiento de la conexión TLS para la solicitud.

Inicio de navegación
Figura 2: El subproceso de IU que se comunica con el subproceso de red para navegar a mysite.com

En este punto, es posible que el subproceso de red reciba un encabezado de redireccionamiento del servidor, como HTTP 301. En ese caso, el subproceso de red se comunica con el subproceso de IU que el servidor solicita redireccionamiento. Luego, se iniciará otra solicitud de URL.

Paso 3: Lee la respuesta

Respuesta HTTP
Figura 3: Encabezado de respuesta que contiene el tipo de contenido y la carga útil, que son los datos reales.

Una vez que comienza a recibir el cuerpo de la respuesta (carga útil), el subproceso de red analiza los primeros bytes de la transmisión si es necesario. El encabezado Content-Type de la respuesta debe indicar de qué tipo son los datos, pero como pueden faltarlos o ser incorrectos, el sniffing de tipo MIME se realiza aquí. Esta es una "empresa complicada", como se comenta en el código fuente. Puedes leer el comentario para ver cómo tratan los pares de tipo de contenido/carga útil en los distintos navegadores.

Si la respuesta es un archivo HTML, el siguiente paso sería pasar los datos al proceso del procesador, pero si es un archivo ZIP o algún otro archivo, significa que se trata de una solicitud de descarga, por lo que deben pasar los datos al administrador de descargas.

Sniffing de tipos de MIME
Figura 4: Subproceso de red que pregunta si los datos de respuesta son HTML de un sitio seguro

Aquí también se lleva a cabo la verificación de SafeBrowsing. Si el dominio y los datos de respuesta parecen coincidir con un sitio malicioso conocido, las alertas del subproceso de red mostrarán una página de advertencia. Además, se realiza la verificación del C Crigen Cead Clocking (C) para garantizar que los datos sensibles de varios sitios no lleguen al proceso del renderizador.

Paso 4: Busca un proceso del renderizador

Una vez que se completan todas las verificaciones y el subproceso de red está seguro de que el navegador debe navegar al sitio solicitado, el subproceso de red le indica al subproceso de IU que los datos están listos. Luego, el subproceso de IU encuentra un proceso de renderización para continuar con la renderización de la página web.

Cómo buscar el proceso del procesador
Figura 5: Subproceso de red que le indica al subproceso de IU que busque el proceso del procesador

Dado que la solicitud de red puede tardar varios cientos de milisegundos en obtener una respuesta, se aplica una optimización para acelerar este proceso. Cuando el subproceso de IU envía una solicitud de URL al subproceso de red en el paso 2, ya sabe a qué sitio navega. El subproceso de IU intenta encontrar o iniciar de forma proactiva un proceso del renderizador en paralelo a la solicitud de red. De esta manera, si todo sale como se espera, un proceso del renderizador ya se encuentra en posición de espera cuando el subproceso de red recibe datos. Es posible que este proceso en espera no se use si la navegación redirecciona a varios sitios, en cuyo caso podría ser necesario otro proceso.

Paso 5: Confirma la navegación

Ahora que los datos y el proceso del renderizador están listos, se envía una IPC del proceso del navegador al proceso del procesador para confirmar la navegación. También pasa el flujo de datos para que el proceso del procesador pueda seguir recibiendo datos HTML. Una vez que el proceso del navegador escucha la confirmación de que se realizó la confirmación en el proceso del procesador, se completa la navegación y comienza la fase de carga del documento.

En este punto, la barra de direcciones se actualiza, y el indicador de seguridad y la IU de la configuración del sitio reflejan la información de la página nueva. Se actualizará el historial de sesión de la pestaña, de modo que los botones Atrás/adelante recorrerán el sitio al que se acaba de navegar. Para facilitar el restablecimiento de pestañas o sesiones cuando cierras una pestaña o ventana, el historial de la sesión se almacena en el disco.

Confirma la navegación
Figura 6: IPC entre el navegador y los procesos del renderizador, que solicita renderizar la página

Paso adicional: Se completó la carga inicial

Una vez que se confirma la navegación, el proceso del renderizador continúa con la carga de recursos y renderiza la página. Analizaremos los detalles de lo que ocurre en esta etapa en la próxima publicación. Una vez que el proceso del procesador "finaliza" la renderización, envía una IPC al proceso del navegador (esto ocurre después de que todos los eventos onload se activan en todos los fotogramas de la página y finalizan su ejecución). En este punto, el subproceso de IU detiene el ícono giratorio de carga en la pestaña.

Digo “finalizar” porque el JavaScript del cliente aún podría cargar recursos adicionales y renderizar vistas nuevas después de este punto.

La página terminó de cargarse
Figura 7: IPC del procesador al proceso del navegador para notificar que se "carga" la página

¡La navegación sencilla estaba completa! Pero ¿qué sucede si un usuario vuelve a colocar una URL diferente en la barra de direcciones? El proceso del navegador sigue los mismos pasos para navegar al sitio diferente. Sin embargo, antes de hacerlo, debe verificar con el sitio renderizado si le interesa el evento beforeunload.

beforeunload puede crear la alerta "¿Quieres salir de este sitio?" cuando intentes salir de este sitio o cerrar la pestaña. Todo el contenido de una pestaña, incluido tu código JavaScript, se controla mediante el proceso del renderizador, por lo que el proceso del navegador debe verificarlo con el proceso actual del procesador cuando llega una nueva solicitud de navegación.

controlador de evento beforeunload
Figura 8: IPC del proceso de navegador a un proceso del procesador que indica que está a punto de navegar a un sitio diferente

Si la navegación se inició desde el proceso del renderizador (por ejemplo, si el usuario hizo clic en un vínculo o si el JavaScript del cliente ejecutó window.location = "https://newsite.com"), este proceso primero verifica los controladores beforeunload. Luego, pasa por el mismo proceso que la navegación iniciada por el proceso del navegador. La única diferencia es que la solicitud de navegación se inicia desde el proceso del procesador hasta el proceso del navegador.

Cuando la navegación nueva se dirige a un sitio diferente del que se renderiza actualmente, se llama a un proceso de renderización independiente para controlar la navegación nueva, mientras que el proceso de renderización actual se conserva para controlar eventos como unload. Para obtener más información, consulta una descripción general de los estados del ciclo de vida de las páginas y cómo puedes conectarte a eventos con la API de Page Lifecycle.

nueva navegación y descargar
Figura 9: 2 IPC de un proceso de navegador a un nuevo proceso del procesador que indica que se renderice la página y que se le indique al proceso anterior que se descargue

En caso de Service Worker

Un cambio reciente en este proceso de navegación es la introducción del service worker. El service worker es una forma de escribir el proxy de red en el código de tu aplicación, lo que permite a los desarrolladores web tener más control sobre lo que se debe almacenar en caché de forma local y cuándo obtener nuevos datos de la red. Si el service worker está configurado para cargar la página desde la caché, no es necesario solicitar los datos de la red.

La parte importante que se debe recordar es que el service worker es código JavaScript que se ejecuta en un proceso de renderización. Pero, cuando llega la solicitud de navegación, ¿cómo sabe un proceso de navegador que el sitio tiene un service worker?

Búsqueda del alcance del service worker
Figura 10: El subproceso de red en el proceso del navegador que busca el alcance del service worker

Cuando se registra un service worker, su alcance se conserva como referencia (puedes obtener más información sobre el alcance en este artículo El ciclo de vida del service worker). Cuando se produce una navegación, el subproceso de red compara el dominio con los alcances del service worker registrados. Si se registra un service worker para esa URL, el subproceso de IU encuentra un proceso del renderizador a fin de ejecutar el código del service worker. El service worker puede cargar datos de la caché, lo que elimina la necesidad de solicitar datos de la red, o puede solicitar nuevos recursos de la red.

navegación de serviceworker
Figura 11: El subproceso de IU en un proceso de navegador que inicia un proceso del procesador para controlar los service workers; un subproceso de trabajo de un proceso del procesador solicita datos de la red

Puedes ver que este recorrido de ida y vuelta entre el proceso del navegador y el del procesador puede generar retrasos si el service worker decide finalmente solicitar datos de la red. La precarga de Navigation es un mecanismo para acelerar este proceso mediante la carga de recursos en paralelo al inicio del service worker. Marca estas solicitudes con un encabezado, lo que permite que los servidores decidan enviar contenido diferente para estas solicitudes; por ejemplo, solo datos actualizados en lugar de un documento completo.

Carga previa de Navigation
Figura 12: El subproceso de IU en un proceso de navegador que inicia un proceso del procesador para controlar el service worker mientras se inicia la solicitud de red en paralelo

Conclusión

En esta publicación, observamos lo que sucede durante una navegación y cómo el código de tu aplicación web, como los encabezados de respuesta y el código JavaScript del cliente, interactúan con el navegador. Conocer los pasos que realiza el navegador para obtener datos de la red facilita la comprensión de por qué se desarrollaron las APIs como la precarga de navegación. En la próxima publicación, analizaremos cómo el navegador evalúa nuestro código HTML/CSS/JavaScript para procesar las páginas.

¿Te gustó la publicación? Si tienes preguntas o sugerencias para la próxima publicación, comunícate con nosotros en la sección de comentarios que aparece a continuación o en @kosamari en Twitter.

Siguiente: Funcionamiento interno de un proceso del procesador