Arquitectura de RenderingNG

Chris Harrelson
Chris Harrelson

Aquí descubrirás cómo el componente RenderingNG se configuran y cómo fluye la canalización de renderización a través de ellas.

A partir del nivel más alto, las tareas de renderización son las siguientes:

  1. Renderiza el contenido en píxeles en la pantalla.
  2. Anima efectos visuales en el contenido de un estado a otro.
  3. Desplazamiento en respuesta a la entrada.
  4. Enruta las entradas de manera eficiente a los lugares correctos para que las secuencias de comandos para desarrolladores y otros subsistemas puedan responder.

El contenido que se renderizará es un árbol de marcos para cada pestaña del navegador, más el elemento del navegador. Y un flujo de eventos de entrada sin procesar desde pantallas táctiles, mouses, teclados y otros dispositivos de hardware.

Cada marco incluye lo siguiente:

  • Estado del DOM
  • CSS
  • Lienzos
  • Recursos externos, como imágenes, videos, fuentes y SVG

Un marco es un documento HTML, más su URL. Una página web cargada en una pestaña del navegador tiene un marco de nivel superior, marcos secundarios para cada iframe incluido en el documento de nivel superior y sus elementos subordinados de iframe recurrentes.

Un efecto visual es una operación gráfica aplicada a un mapa de bits. como desplazar, transformar, recortar, filtro, opacidad o combinación.

Componentes de la arquitectura

En RenderingNG, estas tareas se dividen de forma lógica en varias etapas y códigos o los componentes de la solución. Los componentes terminan en varios procesos de CPU, subprocesos y subcomponentes dentro de esos subprocesos. Cada uno desempeña un papel importante para lograr confiabilidad, rendimiento escalable y extensibilidad para todo el contenido web.

Estructura de la canalización de renderización

Diagrama de la canalización de renderización.
Las flechas indican las entradas y salidas de cada etapa. Etapas se notan por color para demostrar qué subproceso o proceso ejecutan. En En algunos casos, las etapas pueden ejecutarse en varios lugares, dependiendo del circunstancia, por lo que algunos tienen dos colores. Las etapas verdes representan el subproceso principal del proceso de renderización: amarillo son los compositores del proceso de renderización; las etapas naranja son el proceso de visualización.

La renderización procede en una canalización con una serie de etapas y artefactos creados durante el proceso. Cada etapa representa el código que realiza una tarea bien definida en y procesamiento. Los artefactos son estructuras de datos que son entradas o salidas de las etapas.

Las etapas son las siguientes:

  1. Animar: Cambia los estilos calculados y muta los árboles de propiedades a lo largo del tiempo en función de cronogramas declarativos.
  2. Estilo: Aplica CSS al DOM y crea estilos computados.
  3. Diseño: Determina el tamaño y la posición de los elementos DOM en la pantalla. y crea el árbol de fragmentos inmutable.
  4. Prepintura: calcula árboles de propiedades y invalidar cualquier lista de visualización y mosaicos de textura de GPU existentes, según corresponda.
  5. Desplazamiento: Actualiza el desplazamiento de los documentos y elementos del DOM desplazables. Para ello, cambia los árboles de propiedades.
  6. Paint: calcula una lista de visualización en la que se describe cómo generar tramas de mosaicos de texturas de GPU desde el DOM.
  7. Confirmación: Copia los árboles de propiedades y la lista de visualización en el subproceso del compositor.
  8. Layerize: Divide la lista de visualización en una lista de capas compuestas para lograr una rasterización y animación independientes.
  9. Worklets de trama, decodificación y pintura: convierte las listas de visualización, las imágenes codificadas y el código del worklet de pintura, respectivamente, en Mosaicos de texturas de GPU.
  10. Activar: Crea un marco del compositor que represente cómo dibujar y posicionar mosaicos de GPU en la pantalla, junto con cualquier efecto visual.
  11. Aggregate: Combina los fotogramas del compositor de todos los fotogramas visibles del compositor en un solo fotograma global.
  12. Draw: Ejecuta el marco agregado del compositor en la GPU para crear píxeles en la pantalla.

Se pueden omitir las etapas de la canalización de renderización si no son necesarias. Por ejemplo, las animaciones de efectos visuales y el desplazamiento pueden omitir el diseño, la pintura previa y la pintura. Es por eso que la animación y el desplazamiento están marcados con puntos amarillos y verdes en el diagrama. Si se pueden omitir el diseño, el proceso de pintura previo y la pintura para los efectos visuales, se pueden ejecutar completamente en el subproceso del compositor y omitir el subproceso principal.

La renderización de la IU del navegador no se muestra directamente aquí, pero puede considerarse una versión simplificada de esta misma canalización (y de hecho, su implementación comparte gran parte del código). Video (tampoco representado directamente) Por lo general, se renderiza con código independiente que decodifica marcos en mosaicos de texturas de GPU. que luego se conectan a los marcos del compositor y al paso de dibujo.

Estructura de subprocesos y procesos

Procesos de la CPU

El uso de varios procesos de CPU logra un aislamiento de rendimiento y seguridad. entre sitios y del estado del navegador, y aislamiento de estabilidad y seguridad del hardware de la GPU.

Diagrama de las distintas partes de los procesos de la CPU

  • El proceso de renderización renderiza, anima, desplaza y enruta las entradas para una una sola combinación de sitio y pestaña. Existen varios procesos de renderización.
  • El proceso del navegador renderiza, anima y enruta las entradas para la IU del navegador. (incluida la barra de direcciones, los títulos de las pestañas y los íconos), y las rutas restantes de entrada al proceso de renderización adecuado. Hay un proceso del navegador.
  • El proceso de visualización agrega la composición de varios procesos de renderización. además del proceso del navegador. Traza y dibuja con la GPU. Hay proceso de One Viz.

Los diferentes sitios siempre terminan en diferentes procesos de renderización.

Por lo general, varias pestañas o ventanas del navegador de un mismo sitio se renderizan de forma diferente procesos, a menos que las pestañas estén relacionadas, como uno abriendo la otra. Cuando la versión de Chromium en computadoras de escritorio presiona mucho la memoria, es posible que se abran varias pestañas del mismo sitio al mismo proceso de renderización, aunque no estén relacionados.

En una única pestaña del navegador, Los marcos de diferentes sitios están siempre en procesos de renderización diferentes, pero los marcos del mismo sitio siempre están en el mismo proceso de renderización. Desde la perspectiva de la renderización, La ventaja importante de los múltiples procesos de renderización es que los iframes entre sitios y las pestañas logran aislamiento de rendimiento entre sí. Además, los orígenes pueden habilitar aún más aislamiento.

Existe exactamente un proceso de Viz para todo Chromium, ya que, por lo general, solo hay una GPU y una pantalla para dibujar.

Separar Viz en su propio proceso es bueno para la estabilidad frente a errores en hardware o controladores de GPU. También es útil para el aislamiento de seguridad, que es importante para las APIs de GPU, como Vulkan y la seguridad en general.

Como el navegador puede tener muchas pestañas y ventanas, y todos tienen píxeles de la IU del navegador para dibujar, es posible que te preguntes por qué hay exactamente un proceso del navegador. La razón es que solo uno de ellos está enfocado a la vez; de hecho, las pestañas no visibles del navegador se desactivan en su mayoría y descartan toda su memoria de GPU. Sin embargo, cada vez se implementan cada vez más funciones complejas de renderización de la IU del navegador en procesos de renderización también (conocida como WebUI). No es por aislamiento de rendimiento pero para aprovechar la facilidad de uso del motor de renderización web de Chromium.

En dispositivos Android más antiguos, el proceso de renderización y del navegador se comparten cuando se usan en una WebView. (esto no se aplica a Chromium en Android en general, solo a WebView). En WebView, el proceso del navegador también se comparte con la app de incorporación, y WebView solo tiene un proceso de renderización.

A veces, también existe un proceso de utilidad para decodificar contenido de video protegido. Este proceso no se representa en los diagramas anteriores.

Subprocesos

Los subprocesos ayudan a lograr el aislamiento del rendimiento y la capacidad de respuesta a pesar de las tareas lentas, paralelización de canalizaciones y almacenamiento en búfer múltiple.

Diagrama del proceso de renderización.

  • El subproceso principal ejecuta secuencias de comandos, el bucle de eventos de renderización, el ciclo de vida del documento, prueba de posicionamiento, envío de eventos de secuencia de comandos y análisis de HTML, CSS y otros formatos de datos.
    • Los ayudantes de subprocesos principales realizan tareas como crear mapas de bits y BLOB de imagen que requieren codificación o decodificación.
    • Trabajadores web ejecutar una secuencia de comandos y un bucle de eventos de renderización para OffscreenCanvas.
  • El subproceso del compositor procesa los eventos de entrada, realiza desplazamientos y animaciones de contenido web, calcula la creación de capas óptima del contenido web, y coordina la decodificación de imágenes, los worklets de pintura y las tareas de trama.
    • Los asistentes de subprocesos del compositor coordinan tareas de Viz de trama, y ejecutar tareas de decodificación de imágenes, worklets de pintura y trama de resguardo.
  • Los subprocesos de salida de audio, demuxer o multimedia se decodifican. procesar y sincronizar transmisiones de audio y video. (Recuerda que el video se ejecuta en paralelo con la canalización de procesamiento principal).

Separar el subproceso principal y el del compositor es fundamental aislamiento de rendimiento de animación y desplazamiento del trabajo de subproceso principal.

Solo hay un subproceso principal por proceso de renderización aunque varias pestañas o marcos del mismo sitio puedan terminar en el mismo proceso. Sin embargo, existe aislamiento de rendimiento del trabajo realizado en varias APIs del navegador. Por ejemplo, la generación de mapas de bits y BLOB de imágenes en la API de Canvas se ejecuta en un subproceso auxiliar del subproceso principal.

Del mismo modo, solo hay un subproceso del compositor por proceso de renderización. Por lo general, no es un problema que solo haya uno, ya que las operaciones costosas en el subproceso del compositor se delegan a los subprocesos de trabajo del compositor o al proceso de Viz, que puede realizarse en paralelo con el enrutamiento de entrada, el desplazamiento o la animación. Los subprocesos de trabajo del compositor coordinan las tareas que se ejecutan en el proceso de Viz, pero la aceleración de GPU en todas partes pueden fallar por razones fuera del control de Chromium como los errores del controlador. En estas situaciones, el subproceso de trabajo realizará el trabajo en modo de resguardo en la CPU.

La cantidad de subprocesos trabajadores del compositor depende de las capacidades del dispositivo. Por ejemplo, las computadoras de escritorio suelen usar más conversaciones ya que tienen más núcleos de CPU y tienen menos limitaciones de batería que los dispositivos móviles. Este es un ejemplo de el escalamiento vertical y la reducción vertical de la escala.

La arquitectura de subprocesos del proceso de renderización es una aplicación de tres opciones de optimización:

  • Subtareas de ayuda: Envía subtareas de larga duración a subprocesos adicionales para mantenerlas. que el subproceso superior responda a otras solicitudes simultáneas. El subproceso principal Los subprocesos auxiliares y del compositor son buenos ejemplos de esta técnica.
  • Almacenamiento en búfer múltiple: muestra contenido renderizado anteriormente mientras se renderiza contenido nuevo, para ocultar el la latencia de la renderización. El subproceso compositor usa esta técnica.
  • Paralelización de canalizaciones: Ejecuta la canalización de renderización en varios lugares. al mismo tiempo. Así es como el desplazamiento y la animación pueden ser rápidos; incluso si un se está realizando la actualización de renderización del subproceso principal, el desplazamiento y la animación que se ejecutan en paralelo.

Proceso del navegador

Un diagrama del proceso del navegador que muestra la relación entre la renderización y el subproceso de composición, y el asistente de renderización y del subproceso de composición.

  • El subproceso de renderización y composición responde a las entradas en la IU del navegador. enruta otras entradas al proceso de renderización correcto; establece y pinta la IU del navegador.
  • Los asistentes de subprocesos de renderización y composición ejecutar tareas de decodificación de imágenes y decodificación o trama de resguardo.

La renderización del proceso del navegador y la composición del subproceso son similares. en el código y la funcionalidad de un proceso de renderización, con la excepción de que el subproceso principal y el del compositor se combinan en uno. En este caso, solo se necesita un subproceso, ya que no es necesario aislamiento de rendimiento de tareas largas del subproceso principal ya que no existen de por qué.

Proceso de visualización

El proceso Viz incluye el subproceso principal de la GPU y el subproceso compositor de pantalla.

  • El subproceso principal de la GPU muestra listas y fotogramas de video en mosaicos de texturas de GPU. y dibuja marcos del compositor en la pantalla.
  • El subproceso del compositor de la pantalla agrega y optimiza la composición de cada proceso de renderización. y el proceso del navegador, en un único marco del compositor para presentar en la pantalla.

La trama y el dibujo generalmente ocurren en el mismo subproceso, porque ambos dependen de recursos de GPU, y es difícil usar varios subprocesos de la GPU de manera confiable (El acceso multiproceso más sencillo a la GPU es una de las motivaciones para desarrollar el nuevo Vulkan). En WebView de Android, hay un subproceso de renderización independiente a nivel del SO para dibujar. debido a la forma en que las WebViews se incorporan en una app nativa. Es probable que otras plataformas tengan este tipo de conversaciones en el futuro.

El compositor de anuncios gráficos está en un subproceso diferente porque debe ser responsivo en todo momento. y no bloquear ninguna posible fuente de demora en el subproceso principal de la GPU. Una de las causas de la demora en el subproceso principal de la GPU son las llamadas a códigos que no son de Chromium. como controladores de GPU específicos de proveedores, que pueden ser lentos de formas difíciles de predecir.

Estructura de los componentes

Dentro de cada subproceso principal o del compositor del proceso de renderización, hay componentes de software lógicos que interactúan entre sí de formas estructuradas.

Componentes del subproceso principal del proceso de renderización

Diagrama del procesador Blink.

En el procesador Blink:

  • El fragmento de árbol de marcos local representa el árbol de los marcos locales y el DOM dentro de los marcos.
  • El componente de las APIs de DOM y Canvas contiene implementaciones de todas estas APIs.
  • El ejecutor del ciclo de vida del documento ejecuta los pasos de la canalización de renderización, incluido el paso de confirmación.
  • El componente de prueba de posicionamiento y envío del evento de entrada ejecuta pruebas de posicionamiento para Descubrir a qué elemento del DOM se orienta un evento y ejecutar el evento de entrada los algoritmos de envío y los comportamientos predeterminados.

El programador y ejecutor de bucle de eventos de renderización decide qué ejecutar en el evento. y cuándo. Programa que el procesamiento se realice a una cadencia que coincida con el dispositivo. pantalla.

Diagrama del árbol de marcos.

Los fragmentos del árbol de marcos locales son un poco complicados. Recuerda que un árbol de marcos es la página principal y sus iframes secundarios, de manera recursiva. Un fotograma es local para un proceso de renderización si se renderiza en ese proceso. o de manera remota.

Puedes imaginar para colorear marcos según su proceso de renderización. En la imagen anterior, los círculos verdes son todos marcos en un proceso de renderización. los anaranjados están en un segundo y el azul está en un tercero.

Un fragmento de árbol de marcos local es un componente conectado del mismo color en un árbol de marcos. Hay cuatro árboles de marco locales en la imagen: dos para el sitio A, uno para el sitio B y uno para el sitio C. Cada árbol de fotogramas local recibe su propio componente del procesador Blink. El procesador Blink de un árbol de fotogramas local puede o no estar en el mismo proceso de renderización como otros árboles enmarcadores locales. Se determina según la forma en que se seleccionan los procesos de renderización, como se describió antes.

Estructura de subprocesos del compositor del proceso de renderización

Diagrama que muestra los componentes del compositor del proceso de renderización.

Entre los componentes del compositor del proceso de renderización, se incluyen los siguientes:

  • Un controlador de datos que mantiene una lista de capas compuesta, listas de visualización y árboles de propiedades.
  • Un ejecutor de ciclo de vida que ejecuta las funciones animaciones, desplazamiento, composición, trama y decodificar y activar los pasos de la canalización de renderización. (Recuerda que la animación y el desplazamiento pueden ocurrir tanto en el subproceso principal como en el compositor).
  • Un controlador de pruebas de posicionamiento y entrada realiza el procesamiento de entrada y las pruebas de posicionamiento en la resolución de las capas compuestas. para determinar si los gestos de desplazamiento pueden ejecutarse en el subproceso del compositor. y a qué procesos de renderización deben orientarse las pruebas de posicionamiento.

Arquitectura de ejemplo en la práctica

En este ejemplo, hay tres pestañas:

Pestaña 1: foo.com

<html>
  <iframe id=one src="foo.com/other-url"></iframe>
  <iframe  id=two src="bar.com"></iframe>
</html>

Pestaña 2: bar.com

<html>
 …
</html>

Tab 3: baz.com (en inglés) html <html> … </html>

El proceso, el subproceso y la estructura de los componentes de estas pestañas se ven de la siguiente manera:

Diagrama del proceso para las pestañas.

Analicemos un ejemplo de cada una de las cuatro tareas principales de renderización. Recuerda lo siguiente:

  1. Renderiza el contenido en píxeles en la pantalla.
  2. Anima efectos visuales en el contenido de un estado a otro.
  3. Desplazamiento en respuesta a la entrada.
  4. Enruta las entradas de manera eficiente a los lugares correctos para que las secuencias de comandos para desarrolladores y otros subsistemas puedan responder.

Para renderizar el DOM modificado en la pestaña uno, haz lo siguiente:

  1. La secuencia de comandos de un desarrollador cambia el DOM en el proceso de renderización de foo.com.
  2. El renderizador Blink le indica al compositor que debe renderizarse.
  3. El compositor le indica a Viz que necesita una renderización.
  4. La visualización le indica al compositor el inicio de la renderización.
  5. El compositor envía la señal de inicio al renderizador Blink.
  6. El ejecutor de bucles de eventos del subproceso principal ejecuta el ciclo de vida del documento.
  7. El subproceso principal envía el resultado al subproceso del compositor.
  8. El ejecutor de bucle de eventos del compositor ejecuta el ciclo de vida de la composición.
  9. Todas las tareas de trama se envían a Viz para tramas (a menudo, hay más de una de estas tareas).
  10. Visualiza contenido de tramas en la GPU.
  11. Viz confirma la finalización de la tarea de trama. Nota: Chromium no suele esperar a que se complete la trama, sino que usa algo llamado token de sincronización que debe resolverse por tareas de trama antes de que se ejecute el paso 15.
  12. Se envía un marco del compositor a Viz.
  13. Viz agrega los marcos del compositor para el proceso de renderizado de foo.com el proceso de renderización de iframe de bar.com y la IU del navegador.
  14. Viz programa un sorteo.
  15. La visualización dibuja el marco agregado del compositor en la pantalla.

Para animar una transición de transformación de CSS en la pestaña dos, haz lo siguiente:

  1. El subproceso del compositor para el proceso de renderización de bar.com marca una animación en el bucle de eventos del compositor mediante la mutación de los árboles de propiedades existentes. Luego, se vuelve a ejecutar el ciclo de vida del compositor. (Las tareas de trama y decodificación pueden ocurrir, pero no se muestran aquí).
  2. Se envía un marco del compositor a Viz.
  3. Viz agrega los marcos del compositor para el proceso de representación de foo.com, el proceso de representación de bar.com y la IU del navegador.
  4. Viz programa un sorteo.
  5. La visualización dibuja el marco agregado del compositor en la pantalla.

Para desplazarte por la página web en la pestaña tres, haz lo siguiente:

  1. Llega una secuencia de eventos input (mouse, toque o teclado) al proceso del navegador.
  2. Cada evento se enruta al subproceso compositor del proceso de renderización de baz.com.
  3. El compositor determina si el subproceso principal debe conocer el evento.
  4. El evento se envía, de ser necesario, al subproceso principal.
  5. El subproceso principal activa objetos de escucha de eventos input. (pointerdown, touchstar, pointermove, touchmove o wheel) para ver si los objetos de escucha llamarán a preventDefault en el evento.
  6. El subproceso principal muestra si se llamó a preventDefault al compositor.
  7. De lo contrario, el evento de entrada se devuelve al proceso del navegador.
  8. El proceso del navegador lo convierte en un gesto de desplazamiento al combinarlo con otros eventos recientes.
  9. El gesto de desplazamiento se envía una vez más al subproceso compositor del proceso de renderización de baz.com.
  10. Allí se aplica el desplazamiento, y el subproceso compositor para bar.com el proceso de renderización marca una animación en su bucle de eventos del compositor. Luego, cambia el desplazamiento de desplazamiento en los árboles de propiedades y vuelve a ejecutar el ciclo de vida del compositor. También le indica al subproceso principal que active un evento scroll (no se muestra aquí).
  11. Se envía un marco del compositor a Viz.
  12. Viz agrega los marcos del compositor para el proceso de renderizado de foo.com el proceso de renderización de bar.com y la IU del navegador.
  13. Viz programa un sorteo.
  14. La visualización dibuja el marco agregado del compositor en la pantalla.

Para enrutar un evento click en un hipervínculo en el iframe núm. dos en la pestaña uno:

  1. Se activa un evento input (mouse, panel táctil o teclado) al proceso del navegador. Realiza una prueba de posicionamiento aproximada para determinar que el proceso de renderización de iframe de bar.com debería recibir el clic y lo envía allí.
  2. El subproceso compositor de bar.com enruta el evento click al subproceso principal para bar.com y programa una tarea de bucle de eventos de renderización para procesarlo.
  3. El procesador de eventos de entrada para las pruebas de hits del subproceso principal de bar.com a fin de determinar qué Se hizo clic en el elemento DOM del iframe y activa un evento click para que las secuencias de comandos lo observen. Al escuchar que no hay preventDefault, se navega al hipervínculo.
  4. Cuando se carga la página de destino del hipervínculo, se renderiza el estado nuevo. con pasos similares a “render changed DOM” ejemplo anterior. (Los cambios posteriores no se muestran aquí).

Comida para llevar

Puede llevar mucho tiempo recordar e internalizar el funcionamiento de la renderización.

Lo más importante es que la canalización de renderizado la modularización y la atención al detalle, se dividieron y los componentes independientes. Luego, estos componentes se dividieron en direcciones procesos y subprocesos para maximizar rendimiento escalable y de extensibilidad.

Cada componente desempeña un papel fundamental para habilitar el rendimiento y las funciones de aplicaciones web modernas.

Sigue leyendo sobre las estructuras de datos clave. que son tan importantes para RenderingNG como los componentes de código.


Ilustraciones de Una Kravets.