Contención de CSS en Chrome 52

A modo de resumen

La nueva propiedad de contención de CSS permite a los desarrolladores limitar el alcance de los estilos, el diseño y el trabajo de pintura del navegador.

Contención de CSS Antes: el diseño tardaba 59.6 ms. Después: el diseño tarda 0.05 ms

Tiene algunos valores, por lo que su sintaxis es la siguiente:

    contain: none | strict | content | [ size || layout || style || paint ]

Está disponible en Chrome 52 y en Opera 40 y en versiones posteriores (y tiene compatibilidad pública con Firefox), así que inténtalo y cuéntanos cómo te fue.

La propiedad Contiene

Al crear una aplicación web, o incluso un sitio complejo, un desafío clave de rendimiento es limitar los efectos de los estilos, el diseño y la pintura. A menudo, la totalidad del DOM se considera “dentro del alcance” del trabajo de cálculo, lo que puede significar que intentar una “vista” independiente en una app web puede resultar complicado: los cambios en una parte del DOM pueden afectar otras partes, y no hay forma de indicarle al navegador lo que debería estar dentro o fuera del alcance.

Por ejemplo, supongamos que parte de tu DOM se ve de la siguiente manera:

    <section class="view">
      Home
    </section>

    <section class="view">
      About
    </section>

    <section class="view">
      Contact
    </section>

Y agregas un nuevo elemento a una vista, lo que activará estilos, diseño y pintura:

    <section class="view">
      Home
    </section>

    <section class="view">
      About
      <div class="newly-added-element">Check me out!</div>
    </section>

    <section class="view">
      Contact
    </section>

Sin embargo, en este caso, todo el DOM está dentro del alcance, lo que significa que los cálculos de estilo, diseño y pintura deberán considerar todos los elementos, independientemente de si se modificaron o no. Cuanto más grande sea el DOM, más trabajo de cómputos involucra, lo que significa que podrías hacer que tu app no responda a las entradas del usuario.

La buena noticia es que los navegadores modernos se están volviendo muy inteligentes a la hora de limitar el alcance de los estilos, el diseño y el trabajo de pintura de forma automática, lo que significa que las cosas se vuelven más rápidas sin que tengas que hacer nada.

Sin embargo, la noticia aún mejor es que existe una nueva propiedad de CSS que entrega los controles de alcance a los desarrolladores: la contención.

CSS Containment es una propiedad nueva, con la palabra clave "contains", que admite cuatro valores:

  • layout
  • paint
  • size
  • style

Cada uno de estos valores te permite limitar la cantidad de trabajo de renderización que debe realizar el navegador. Analicemos cada uno en más detalle.

Diseño (incluye: diseño)

La contención del diseño probablemente sea el mayor beneficio de la contención, junto con contain: paint.

El diseño suele estar centrado en el documento, por lo que se escala de manera proporcional al tamaño de tu DOM. Por lo tanto, si cambias la propiedad left de un elemento, es posible que debas verificar cada uno de los elementos del DOM.

Habilitar la contención aquí podría reducir potencialmente la cantidad de elementos a solo un puñado, en lugar de todo el documento, lo que le ahorra al navegador una gran cantidad de trabajo innecesario y mejora significativamente el rendimiento.

Pintura (contiene: pintura)

La pintura de cobertura es otro beneficio increíblemente útil de la contención. La contención de pintura básicamente recorta el elemento en cuestión, pero también tiene otros efectos secundarios:

  • Actúa como un bloque contenedor para elementos de posición absoluta y fija. Esto significa que cualquier elemento secundario se posiciona según el elemento con contain: paint, no con ningún otro elemento superior, como, por ejemplo, el documento.
  • Se convierte en un contexto de apilamiento. Esto significa que elementos como z-index tendrán un efecto en el elemento y los elementos secundarios se apilan según el nuevo contexto.
  • Se convierte en un nuevo contexto de formato. Esto significa que si tienes, por ejemplo, un elemento de nivel de bloque con contención de pintura, se tratará como un nuevo entorno de diseño independiente. Esto significa que el diseño fuera del elemento no suele afectar a los elementos secundarios del elemento que lo contiene.

Tamaño (incluye: tamaño)

contain: size significa que los elementos secundarios no afectan el tamaño del elemento superior, y que se usarán las dimensiones inferidas o declaradas. En consecuencia, si establecieras contain: size, pero no especificaste dimensiones para el elemento (ya sea directamente o a través de propiedades flexibles), se renderizaría a 0 px por 0 px.

La contención del tamaño es en realidad una medida de cinturón y llaves para garantizar que no dependas de elementos secundarios para el tamaño, pero por sí solo no ofrece muchos beneficios de rendimiento.

Estilo (incluye: style)

Puede resultar difícil predecir cuáles son los efectos en el árbol del DOM de cambiar los estilos de un elemento para respaldar el árbol. Un ejemplo de esto es en algo como los contadores de CSS, donde cambiar un contador en un elemento secundario puede afectar los valores de contador con el mismo nombre que se usan en otras partes del documento. Si estableces contain: style, los cambios de diseño no se propagarán más allá del elemento contenedor.

Para ser más claros, lo que contain: style no proporciona es un estilo con alcance como lo harías con Shadow DOM. la contención solo se trata de limitar las partes del árbol que se consideran cuando se mutan los estilos, no cuando se declaran.

Contención estricta y de contenido

También puedes combinar palabras clave, como contain: layout paint, que solo aplicarán esos comportamientos a un elemento. Pero "contiene" también admite dos valores adicionales:

  • contain: strict significa lo mismo que contain: size layout paint.
  • contain: content significa lo mismo que contain: layout paint.

El uso de la contención estricta es excelente cuando conoces el tamaño del elemento con anticipación (o deseas reservar sus dimensiones), pero ten en cuenta que si declaras una contención estricta sin dimensiones, debido a la contención de tamaño implícita, el elemento se puede renderizar como un cuadro de 0 px por 0 px.

Por otro lado, la contención del contenido ofrece mejoras de alcance significativas, pero no requiere que conozcas ni especifiques las dimensiones del elemento con anticipación.

De los dos, contain: content es el que deberías usar de forma predeterminada. Deberías considerar la contención estricta como una salida de escape cuando contain: content no es lo suficientemente fuerte para tus necesidades.

Cuéntanos cómo te va

La contención es una excelente manera de empezar a indicarle al navegador lo que quieres mantener aislado en tu página. Pruébalo en Chrome 52 y versiones posteriores, y cuéntanos cómo lo haces.