Transiciones de vistas de SPA más rápidas con el almacenamiento en caché de estado

Funciones web: content-visibility

Habilita la navegación instantánea entre vistas en una aplicación de una sola página (SPA) almacenando en caché el estado renderizado de las vistas inactivas en lugar de destruirlas.

Descripción general

Tradicionalmente, cuando un usuario navega entre pestañas o vistas en una SPA, los desarrolladores destruyen la vista anterior o la ocultan con display: none. Ambos enfoques requieren que el navegador vuelva a crear o calcular el diseño completo y lo pinte cuando el usuario regrese a esa vista.

Cuando se usa content-visibility: hidden en vistas inactivas, el navegador quita el contenido del elemento del flujo de diseño y deja de pintarlo, pero conserva su estado de renderización almacenado en caché en la memoria. Cuando el usuario vuelve a cambiar, la vista se restablece casi de inmediato.

Compensación entre CPU y RAM

Si bien este enfoque ofrece enormes beneficios de rendimiento, presenta una compensación específica que debes administrar con cuidado:

  • Ahorro de CPU: Enorme. El navegador omite por completo los pases de diseño y pintura para las vistas ocultas.
  • Costo de RAM: Alto. El navegador mantiene en la memoria todos los nodos del DOM, los objetos de escucha de eventos y el estado de la vista oculta.

Cuándo esta compensación se vuelve peligrosa

  • SÍ usa esta estrategia para aplicaciones sencillas con una cantidad pequeña y predecible de vistas (p.ej., una interfaz con 3 a 5 pestañas).
  • NO almacenes en caché de forma incondicional todas las vistas en aplicaciones muy dinámicas que generen decenas de informes únicos o usen rutas dinámicas infinitas. Si lo haces, con el tiempo se producirá un aumento excesivo de la memoria y es posible que el navegador falle en los dispositivos de gama baja.
  • OBLIGATORIO: Si tu aplicación es muy dinámica, DEBES implementar una estrategia de expulsión (como una caché de uso menos reciente) para destruir las vistas antiguas cuando se alcance un umbral de memoria.

Implementación

1. Configura contenedores de vistas

Establece content-visibility: hidden en las vistas que no están activas en ese momento.

.spa-view.inactive {
  /* MANDATORY: Use hidden to cache the rendering state of inactive views */
  content-visibility: hidden;
  
  /* Optional: Prevent hidden views from taking up physical space in layout flow */
  position: absolute;
}

2. Administra el enfoque

Cuando intercambies vistas, asegúrate de administrar correctamente el enfoque del teclado para preservar la accesibilidad.

function switchToView(viewId) {
  // Hide all views
  document.querySelectorAll('.spa-view').forEach(view => {
    view.classList.add('inactive');
    view.setAttribute('aria-hidden', 'true');
  });
  
  // Show the target view
  const activeView = document.getElementById(viewId);
  activeView.classList.remove('inactive');
  activeView.setAttribute('aria-hidden', 'false');
  
  // MANDATORY: Move focus to the new view to ensure a logical tab-order
  activeView.focus();
}

Estrategias de resguardo

La propiedad content-visibility se degrada de forma ordenada. En los navegadores que no lo admiten, ocurre lo siguiente:

  • Se ignora la propiedad.
  • Para evitar que los navegadores de resguardo rendericen todas las vistas de forma simultánea, debes proporcionar un resguardo para display: none en tu CSS:
@supports not (content-visibility: hidden) {
  .spa-view.inactive {
    display: none;
  }
}