Saltar al contenido

client:load y client:idle: urgencia y paciencia

Las dos directivas del extremo impaciente del espectro: client:load hidrata en cuanto el navegador puede, para lo que debe responder desde el primer instante; client:idle espera a que el hilo principal quede libre con requestIdleCallback, con un timeout opcional que garantiza un tope. Elegir entre ellas es una decisión de planificación del hilo principal, no de velocidad.

client:load: hidrata ya

client:load es la directiva de máxima prioridad. Marca la isla para que se hidrate en cuanto su JavaScript esté disponible, sin esperar a ninguna condición. El runtime importa el framework y el componente de inmediato y ejecuta la hidratación tan pronto como puede, compitiendo por el hilo principal con todo lo demás que arranca al cargar la página.

ASTRO
---import BotonComprar from '../components/BotonComprar.jsx';---<BotonComprar client:load />

Esa urgencia es exactamente lo que quieres para lo que debe funcionar desde el primer segundo y está a la vista al entrar. Son buenos candidatos:

  • Un botón de compra o de acción principal sobre el pliegue.
  • Un menú principal que se despliega al tocarlo.
  • Un campo de búsqueda con foco automático.
  • Un conmutador de tema que evita el parpadeo de color al cargar.

Para todo eso, cualquier demora se percibe como un fallo: el usuario hace clic y no pasa nada. client:load compra respuesta inmediata al precio de gastar hilo principal justo cuando más escaso es. Y ese precio es real: cada isla client:load descarga, analiza y ejecuta su código durante el arranque, el momento en que el navegador ya está ocupado pintando y preparando la página. Un puñado de islas client:load pesadas dispara el TBT y retrasa el momento en que la página responde.

client:idle: hidrata en el respiro

client:idle conserva la garantía de que la isla se hidratará —no depende de que el usuario haga scroll ni de una media query—, pero cede la prioridad: espera a que el hilo principal quede libre. Por debajo usa requestIdleCallback, la API del navegador pensada justo para esto, que ejecuta trabajo de baja prioridad en los huecos entre tareas urgentes. En navegadores sin esa API, Astro recurre a un setTimeout como red de seguridad.

ASTRO
---import Recomendaciones from '../components/Recomendaciones.jsx';---<Recomendaciones client:idle />

Conviene entender qué aplaza exactamente. A diferencia de client:load, que importa el módulo cuanto antes, client:idle programa esa importación y la hidratación para el primer momento ocioso: difiere el trabajo entero, no solo el último paso. El resultado es interactividad que llega un instante después de lo crítico, sin robarle CPU al arranque. Encaja de maravilla en cosas como:

  • Un panel de recomendaciones o de contenido relacionado.
  • Un widget de compartir o de reacciones.
  • Un selector de idioma o de moneda en la cabecera.
  • Adornos y analíticas que deben cargar, pero sin prisa.

Hay un matiz de control fino. client:idle acepta un timeout opcional, client:idle={{timeout: 500}}, que se pasa a requestIdleCallback como tope: si en ese plazo el hilo nunca llega a estar ocioso, el navegador fuerza la hidratación de todos modos. Sirve para poner un límite superior a la espera y evitar que una isla se quede sin hidratar indefinidamente en una página que nunca descansa.

ASTRO
---import Recomendaciones from '../components/Recomendaciones.jsx';---<Recomendaciones client:idle={{timeout: 500}} />

Repartir el hilo principal

Pensar en client:load frente a client:idle como “rápido” frente a “lento” despista. Las dos hidratan pronto; la diferencia es quién va primero cuando varias islas compiten por el mismo hilo. client:load dice “yo antes que la pintura y el resto”; client:idle dice “cuando todos hayan pasado, en el primer hueco”. Es planificación, no velocidad. En una misma página conviven sin coordinarse, cada una con su política declarada al lado:

ASTRO
---import Tema from '../components/Tema.jsx';import Menu from '../components/Menu.jsx';import Recomendaciones from '../components/Recomendaciones.jsx';---<Tema client:load />              <!-- critico: evita el parpadeo de color --><Menu client:load />              <!-- visible y usable al entrar --><Recomendaciones client:idle />   <!-- util, pero puede esperar al respiro -->

Dónde caen en el espectro

Estas dos directivas son solo el extremo impaciente de un abanico de cinco, que conviene tener presente entero desde ya:

  • client:load — la más impaciente: en cuanto llega el código.
  • client:idle — en el primer hueco del hilo principal.
  • client:visible — cuando la isla entra en pantalla.
  • client:media — cuando una media query se cumple.
  • client:only — sin servidor, renderizada entera en el cliente.

Una heurística que envejece bien: reparte tus islas impacientes en dos grupos. Las que el usuario podría tocar en el primer segundo —y que están a la vista— van con client:load. Las demás que igual deben acabar hidratadas sin depender del scroll van con client:idle. Ese simple corte suele bastar para bajar el TBT sin que nadie perciba una pérdida de interactividad, porque lo que se difiere es justo lo que nadie iba a usar en ese primer instante.