Contención de CSS en Chrome 52

A modo de resumen

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

Contención de CSS. Antes: El diseño tarda 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 versiones posteriores, y en Opera 40 y versiones posteriores (y tiene compatibilidad pública con Firefox), así que pruébala y cuéntanos cómo te fue.

La propiedad contain

Cuando se crea una app 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” para el trabajo de procesamiento, lo que puede significar que intentar una “vista” independiente en una app web puede ser complicado: los cambios en una parte del DOM pueden afectar a otras partes, y no hay forma de decirle al navegador qué debe 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 elemento nuevo a una vista, que activará los estilos, el diseño y la 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 cambiaron o no. Cuanto más grande sea el DOM, más trabajo de procesamiento implicará, 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 para limitar el alcance de los estilos, el diseño y el trabajo de pintura automáticamente, lo que significa que todo se vuelve más rápido sin que tengas que hacer nada.

Pero la noticia aún mejor es que hay una nueva propiedad CSS que les entrega a los desarrolladores controles de alcance: Containment.

El aislamiento de CSS es una propiedad nueva, con la palabra clave contain, 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 con más detalle.

Diseño (contain: layout)

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

Por lo general, el diseño se ajusta al alcance del documento, lo que hace que se ajuste proporcionalmente al tamaño de tu DOM. Por lo tanto, si cambias la propiedad left de un elemento, es posible que debas verificar cada elemento del DOM.

Habilitar el aislamiento aquí puede reducir potencialmente la cantidad de elementos a solo unos pocos, en lugar de todo el documento, lo que le ahorra al navegador mucho trabajo innecesario y mejora significativamente el rendimiento.

Pintura (contiene: pintura)

La pintura de alcance es otro beneficio increíblemente útil del aislamiento. La contención de pintura, en esencia, recorta el elemento en cuestión, pero también tiene algunos otros efectos secundarios:

  • Actúa como un bloque contenedor para elementos de posición fija y de posicionamiento absoluto. Esto significa que todos los elementos secundarios se posicionan en función del elemento con contain: paint, no de ningún otro elemento superior, como 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 apilarán según el contexto nuevo.
  • Se convierte en un nuevo contexto de formato. Esto significa que, si tienes, por ejemplo, un elemento a nivel del bloque con contención de pintura, se tratará como un nuevo entorno de diseño independiente. Esto significa que, por lo general, el diseño fuera del elemento no afectará a los elementos secundarios del elemento contenedor.

Tamaño (contiene: tamaño)

Lo que significa contain: size es que los elementos secundarios no afectan el tamaño del elemento superior y que se usarán sus dimensiones inferidas o declaradas. Por lo tanto, si configuraras contain: size, pero no especificaras las dimensiones del elemento (ya sea directamente o a través de propiedades flex), se renderizaría en 0 px por 0 px.

La contención de tamaño es realmente una medida de seguridad para garantizar que no dependas de los elementos secundarios para el tamaño, pero por sí sola no ofrece muchos beneficios de rendimiento.

Estilo (contain: style)

Puede ser difícil predecir cuáles serán los efectos en el árbol del DOM de cambiar los estilos de un elemento en la parte superior del árbol. Un ejemplo de esto es en algo como los contadores de CSS, en los que cambiar un contador en un elemento secundario puede afectar los valores del contador del mismo nombre que se usan en otra parte del documento. Con contain: style establecido, los cambios de estilo no se propagarán más allá del elemento contenedor.

Para que quede muy claro, lo que contain: style no proporciona son los estilos con alcance, como los que obtienes de Shadow DOM. Aquí, la contención se trata solo de limitar las partes del árbol que se tienen en cuenta cuando se modifican los estilos, no cuando se declaran.

Contención estricta y de contenido

También puedes combinar palabras clave, como contain: layout paint, que aplicará solo esos comportamientos a un elemento. Sin embargo, contain 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 contención estricta es ideal cuando conoces el tamaño del elemento con anticipación (o deseas reservar sus dimensiones), pero ten en cuenta que, si declaras la contención estricta sin dimensiones, debido a la contención de tamaño implícita, el elemento puede renderizarse como un cuadro de 0 px por 0 px.

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

De los dos, contain: content es el que debes usar de forma predeterminada. Debes tratar el aislamiento estricto como una salida de emergencia cuando contain: content no sea lo suficientemente sólido para tus necesidades.

Cuéntanos cómo te va

El aislamiento es una excelente manera de comenzar a indicarle al navegador lo que deseas mantener aislado dentro de tu página. Pruébala en Chrome 52 y versiones posteriores, y danos tu opinión.