Mejora el tiempo de carga inicial omitiendo la renderización del contenido fuera de pantalla.
Fecha de publicación: 5 de agosto de 2020
La propiedad content-visibility
permite que el usuario omita el trabajo de renderización de un elemento, incluido el diseño y la pintura, hasta que sea necesario. Debido a que se omite la renderización, si una gran parte de tu contenido está fuera de la pantalla, usar la propiedad content-visibility
hace que la carga inicial del usuario sea mucho más rápida. También permite interacciones más rápidas con el contenido en pantalla. Muy bien.
Contención de CSS
El objetivo clave y general del aislamiento de CSS es permitir mejoras de rendimiento de renderización del contenido web proporcionando un aislamiento predecible de un subárbol del DOM del resto de la página.
Básicamente, un desarrollador puede indicarle a un navegador qué partes de la página están encapsuladas como un conjunto de contenido, lo que permite que los navegadores razonen sobre el contenido sin tener que considerar el estado fuera del subárbol. Saber qué fragmentos de contenido (subárboles) contienen contenido aislado significa que el navegador puede tomar decisiones de optimización para la renderización de páginas.
Existen cuatro tipos de contención de CSS, cada uno de los cuales es un valor potencial para la propiedad CSS contain
, que se puede combinar en una lista de valores separados por espacios:
size
: La contención del tamaño en un elemento garantiza que el cuadro del elemento se pueda distribuir sin necesidad de examinar sus subordinados. Esto significa que podemos omitir el diseño de los elementos secundarios si todo lo que necesitamos es el tamaño del elemento.layout
: El aislamiento de diseño significa que los elementos secundarios no afectan el diseño externo de otros cuadros de la página. Esto nos permite omitir el diseño de los elementos secundarios si todo lo que queremos hacer es diseñar otros cuadros.style
: La contención de estilo garantiza que las propiedades que pueden tener efectos en más de solo sus descendientes no escapen del elemento (p.ej., contadores). Esto nos permite omitir el cálculo de diseño para los descendientes si todo lo que queremos es calcular diseños en otros elementos.paint
: El confinamiento de pintura garantiza que los elementos secundarios del cuadro contenedor no se muestren fuera de sus límites. Nada puede desbordar el elemento de forma visible, y si un elemento está fuera de la pantalla o no es visible, sus elementos secundarios tampoco lo serán. Esto nos permite omitir la pintura de los descendientes si el elemento está fuera de la pantalla.
Omitir el trabajo de renderización con content-visibility
Puede ser difícil determinar qué valores de contención usar, ya que las optimizaciones del navegador solo pueden activarse cuando se especifica un conjunto adecuado. Puedes experimentar con los valores para ver qué funciona mejor, o bien usar content-visibility
para aplicar el aislamiento necesario automáticamente. content-visibility
garantiza que obtengas los mayores aumentos de rendimiento que el navegador puede proporcionar con un esfuerzo mínimo de tu parte como desarrollador.
La propiedad content-visibility acepta varios valores, pero auto
es la que proporciona mejoras de rendimiento inmediatas. Un elemento que tiene content-visibility: auto
obtiene la contención de layout
, style
y paint
. Si el elemento está fuera de la pantalla (y no es relevante para el usuario, los elementos relevantes serían los que tienen enfoque o selección en su subárbol), también obtiene contención size
(y deja de pintar y probar si se produce un hit su contenido).
¿Qué significa esto? En resumen, si el elemento está fuera de la pantalla, no se renderizan sus elementos secundarios. El navegador determina el tamaño del elemento sin considerar ninguno de sus contenidos y se detiene allí. Se omite la mayor parte de la renderización, como el diseño y el estilo del subárbol del elemento.
A medida que el elemento se acerca al viewport, el navegador ya no agrega el contenedor size
y comienza a pintar y realizar pruebas de hit en el contenido del elemento. Esto permite que el trabajo de renderización se realice justo a tiempo para que el usuario lo vea.
Nota sobre la accesibilidad
Una de las características de content-visibility: auto
es que el contenido fuera de la pantalla permanece disponible en el modelo de objetos de documentos y, por lo tanto, en el árbol de accesibilidad (a diferencia de visibility: hidden
). Esto significa que se puede buscar contenido en la página y navegar a él sin esperar a que se cargue ni sacrificar el rendimiento de la renderización.
Sin embargo, la desventaja de esto es que los elementos de referencia con atributos de estilo, como display: none
o visibility: hidden
, también aparecerán en el árbol de accesibilidad cuando estén fuera de la pantalla, ya que el navegador no renderizará estos estilos hasta que ingresen en el viewport. Para evitar que sean visibles en el árbol de accesibilidad y puedan causar desorden, asegúrate de agregar también aria-hidden="true"
.
Ejemplo: un blog de viajes
Por lo general, un blog de viajes contiene un conjunto de historias con algunas imágenes y un texto descriptivo. A continuación, se muestra lo que sucede en un navegador típico cuando se navega a un blog de viajes:
- Una parte de la página se descarga de la red, junto con los recursos necesarios.
- El navegador aplica diseño y estilo a todo el contenido de la página, sin considerar si el usuario puede verlo.
- El navegador vuelve al paso 1 hasta que se descargan todos los recursos y la página.
En el paso 2, el navegador procesa todo el contenido en busca de cambios. Actualiza el estilo y el diseño de los elementos nuevos, junto con los elementos que pueden haber cambiado como resultado de las actualizaciones nuevas. Esto es renderización de trabajo. Esto lleva tiempo.
Ahora, considera lo que sucede si colocas content-visibility: auto
en cada una de las historias individuales del blog. El bucle general es el mismo: el navegador descarga y renderiza fragmentos de la página. Sin embargo, la diferencia está en la cantidad de trabajo que realiza en el paso 2.
Con content-visibility, se aplicará diseño y estilo a todo el contenido que el usuario puede ver en ese momento (está en pantalla). Sin embargo, cuando se procesa la historia que está completamente fuera de la pantalla, el navegador omite el trabajo de renderización y solo aplica diseño y estilo al cuadro del elemento.
El rendimiento de la carga de esta página sería como si contuviera historias completas en pantalla y cuadros vacíos para cada una de las historias fuera de la pantalla. Esto tiene un rendimiento mucho mejor, con una reducción esperada del 50% o más del costo de renderización de la carga. En nuestro ejemplo, observamos un aumento de un tiempo de renderización de 232 ms a un tiempo de renderización de 30 ms. lo que representa un aumento de 7 veces en el rendimiento.
¿Qué debes hacer para obtener estos beneficios? Primero, fragmentamos el contenido en secciones:
A continuación, aplicamos la siguiente regla de estilo a las secciones:
.story {
content-visibility: auto;
contain-intrinsic-size: 1000px; /* Explained in the next section. */
}
Especifica el tamaño natural de un elemento con contain-intrinsic-size
Para aprovechar los posibles beneficios de content-visibility
, el navegador debe aplicar el control de tamaño para garantizar que los resultados de renderización del contenido no afecten el tamaño del elemento de ninguna manera. Esto significa que el elemento se dispondrá como si estuviera vacío. Si el elemento no tiene una altura especificada en un diseño de bloque normal, tendrá una altura de 0.
Es posible que esto no sea lo ideal, ya que el tamaño de la barra de desplazamiento cambiará, ya que depende de que cada historia tenga una altura distinta de cero.
Por suerte, CSS proporciona otra propiedad, contain-intrinsic-size
, que especifica de manera eficaz el tamaño natural del elemento si este se ve afectado por el confinamiento de tamaño. En nuestro ejemplo, lo configuramos en 1000px
como una estimación de la altura y el ancho de las secciones.
Esto significa que se diseñará como si tuviera un solo elemento secundario de dimensiones de "tamaño intrínseco", lo que garantiza que tus divs sin tamaño aún ocupen espacio.
contain-intrinsic-size
actúa como un tamaño de marcador de posición en lugar del contenido renderizado.
La palabra clave auto
para contain-intrinsic-size
hace que el navegador recuerde el tamaño renderizado por última vez, si corresponde, y lo use en lugar del tamaño del marcador de posición proporcionado por el desarrollador. Por ejemplo, si especificaste contain-intrinsic-size: auto 300px
, el elemento comenzará con un tamaño intrínseco de 300px
en cada dimensión, pero una vez que se renderice el contenido del elemento, retendrá el tamaño intrínseco renderizado.
También se recordarán los cambios de tamaño de renderización posteriores. En la práctica, esto significa que, si desplazas un elemento con content-visibility: auto
aplicado y, luego, lo vuelves a desplazar fuera de la pantalla, retendrá automáticamente su ancho y altura ideales, y no volverá al tamaño del marcador de posición. Esta función es especialmente útil para los controles de desplazamiento infinito, que ahora pueden mejorar automáticamente la estimación del tamaño con el tiempo a medida que el usuario explora la página.
Oculta contenido con content-visibility: hidden
¿Qué sucede si quieres mantener el contenido sin renderizar independientemente de si está o no en pantalla y, al mismo tiempo, aprovechar los beneficios del estado de renderización en caché? Ingresa: content-visibility: hidden
.
La propiedad content-visibility: hidden
ofrece los mismos beneficios del contenido no renderizado y el estado de renderización en caché que content-visibility: auto
ofrece fuera de la pantalla. Sin embargo, a diferencia de auto
, no comienza a renderizarse automáticamente en la pantalla.
Esto te brinda más control, lo que te permite ocultar el contenido de un elemento y, luego, ocultarlo rápidamente.
Compara esta técnica con otras formas comunes de ocultar el contenido de un elemento:
display: none
: Oculta el elemento y destruye su estado de renderización. Esto significa que ocultar el elemento es tan costoso como renderizar un elemento nuevo con el mismo contenido.visibility: hidden
: Oculta el elemento y mantiene su estado de renderización. Esto no quita realmente el elemento del documento, ya que (y su subárbol) aún ocupa espacio geométrico en la página y se puede hacer clic en él. También actualiza el estado de renderización cada vez que sea necesario, incluso cuando está oculto.
content-visibility: hidden
, por otro lado, oculta el elemento mientras conserva su estado de renderización, por lo que, si hay algún cambio que se deba realizar, solo se produce cuando se vuelve a mostrar el elemento (es decir, se quita la propiedad content-visibility: hidden
).
Algunos casos de uso excelentes para content-visibility: hidden
son cuando se implementan
deslizadores virtuales avanzados y se mide el diseño. También son excelentes para las aplicaciones de una sola página (SPA). Las vistas de apps inactivas se pueden dejar en el DOM con content-visibility: hidden
aplicado para evitar su visualización, pero mantener su estado almacenado en caché. Esto permite que la vista se renderice rápidamente cuando vuelve a estar activa.
Efectos en la interacción con la siguiente pintura (INP)
INP es una métrica que evalúa la capacidad de una página para responder de forma confiable a las entradas del usuario. La capacidad de respuesta puede verse afectada por cualquier cantidad excesiva de trabajo que se produzca en el subproceso principal, incluida la renderización.
Cada vez que puedes reducir el trabajo de renderización en una página determinada, le das al subproceso principal la oportunidad de responder a las entradas del usuario con mayor rapidez. Esto incluye el trabajo de renderización, y usar la propiedad CSS content-visiblity
cuando corresponda puede reducir el trabajo de renderización, especialmente durante el inicio, cuando se realiza la mayor parte del trabajo de renderización y diseño.
Reducir el trabajo de renderización tiene un efecto directo en la INP. Cuando los usuarios intentan interactuar con una página que usa la propiedad content-visibility
correctamente para aplazar el diseño y la renderización de elementos fuera de la pantalla, le das al subproceso principal la oportunidad de responder a un trabajo crítico visible para el usuario. Esto puede mejorar el INP de tu página en algunas situaciones.
Conclusión
content-visibility
y las especificaciones de contención de CSS implican que algunas mejoras de rendimiento interesantes se incluirán directamente en tu archivo CSS. Para obtener más información sobre estas propiedades, consulta lo siguiente: