Rendimiento CSS, containment y content-visibility | Nicolás Garzón
El rendimiento CSS depende de cuánto trabajo provoca una actualización en style calculation, layout, paint y compositing.
Texto
Copiar cambio de estado
↓
style
↓
layout cuando cambia geometría
↓
paint cuando cambian píxeles
↓
composite cuando cambian capasHTML
Copiar < link rel = " stylesheet" href = " /styles.css" > Una stylesheet necesaria bloquea renderizado para evitar pintar contenido con estilos incompletos.
CSS inicial razonable.
Cache.
Compresión.
Eliminación de imports encadenados.
División por rutas cuando realmente reduce el camino crítico.
Fragmentar en demasiados archivos también tiene costo.
Una gran stylesheet aumenta transferencia, parsing y memoria. Herramientas de build pueden eliminar utilities no detectadas, pero clases construidas dinámicamente pueden desaparecer por error.
Prueba el artefacto de producción.
Los motores modernos optimizan selección. Evita obsesionarte con div > span frente a .label sin medir.
Los problemas reales suelen ser:
DOM enorme.
Selectores globales amplios.
:has() sobre árboles muy dinámicos y extensos.
Cambios frecuentes en ancestors que invalidan muchos descendientes.
Reglas y custom properties globales que afectan toda la página.
CSS no provoca por sí solo el patrón; JavaScript que alterna lecturas y escrituras puede forzar layouts síncronos:
JavaScript
Copiar item. style. width = '200px' ;
const height = item. offsetHeight; Agrupa writes y reads o utiliza APIs de observación.
CSS
Copiar .widget {
contain : layout paint;
}
size
inline-size
layout
style
paint
Shorthands como strict y content combinan varios.
Containment promete que ciertos cambios no afectan fuera. Una promesa incorrecta puede cambiar sizing o recortar contenido.
CSS
Copiar .widget {
contain : size;
contain-intrinsic-size : 20rem 30rem;
} El elemento deja de usar su contenido para sizing externo y necesita una dimensión o intrinsic placeholder apropiado.
CSS
Copiar .section {
content-visibility : auto;
contain-intrinsic-block-size : auto 40rem;
} Permite omitir rendering de contenido fuera de pantalla mientras conserva una estimación de tamaño.
El contenido continúa en DOM y puede participar en búsqueda, accesibilidad y navegación según reglas del navegador; prueba focus y fragment navigation.
Sin estimación, saltos de layout pueden aparecer cuando el contenido entra al área renderizada.
CSS
Copiar contain-intrinsic-size : auto 600px; auto puede recordar tamaño tras renderizar y usar un fallback inicial.
CSS
Copiar .card:hover {
will-change : transform;
} No debería aplicarse solo durante hover porque el navegador necesita anticipación. Tampoco debe quedar en cientos de elementos.
Úsalo temporalmente antes de una animación conocida y retíralo después cuando sea viable.
will-change puede crear stacking context o consumir memoria.
Transform y opacity suelen evitar layout y paint del contenido, pero:
Crear layers consume memoria.
Grandes surfaces cuestan transferir y componer.
Filters y backdrop filters pueden repintar.
Texto escalado puede perder calidad.
Overdraw sigue existiendo.
Evita animar continuamente:
Box shadows grandes.
Filters sobre áreas extensas.
Width/height de layouts complejos.
Background-position en imágenes enormes.
Mide frames, paint y GPU memory en hardware real.
Cambiar un token en :root puede invalidar estilos de muchos descendientes. Para estado local, define la property en el subtree más pequeño posible.
Muchos query containers no son automáticamente un problema, pero añaden containment y reevaluación contextual. No declares container-type globalmente en cada div.
CSS de fuentes afecta rendimiento mediante:
Cantidad de archivos.
Fallback metrics.
Preload.
Font-display.
Glyph coverage.
El objetivo no es ocultar texto, sino mostrar contenido estable pronto.
Coverage.
Performance trace.
Rendering/paint flashing.
Layers.
Layout shifts.
Computed styles.
Network priority.
Un Lighthouse score no explica por sí solo la causa.
CSS
Copiar .project-list {
content-visibility : auto;
contain-intrinsic-block-size : auto 50rem;
} Aporta en listas largas debajo del fold; no lo apliques al hero o contenido LCP.
Considerar cualquier selector complejo lento.
Aplicar contain sin entender sizing.
Usar content-visibility en contenido crítico.
Añadir will-change a todo.
Crear cientos de compositor layers.
Animar blur grande.
Cambiar tokens globales para estado local.
Optimizar una métrica sin medir experiencia.
CSS participa en varias etapas de rendering.
El camino crítico y CSS no usado importan.
Containment limita dependencias a cambio de restricciones.
Content-visibility puede omitir trabajo fuera de pantalla.
Intrinsic placeholders reducen saltos.
Will-change es una pista costosa.
Transform y opacity no son mágicamente gratis.
Mide en producción y hardware real.
¿Por qué will-change: transform en cientos de cards puede empeorar rendimiento?
Respuesta Porque puede promover muchas capas, consumir memoria y aumentar trabajo de composición aunque la mayoría nunca se anime.
Debugging, @supports y compatibilidad crea una estrategia para encontrar y contener fallos.