Defer Block en Angular
Parte fundamental de la nueva sintaxis de Control Flow en específico las Deferrable Views o (Vistas Diferidas) son una nueva etiqueta, la etiqueta @defer
, Además de todas las nuevas funcionalidades que podemos aprovechar para que nuestro código sea más legible y que lograr mejores interacciones de manera más fácil y así mejorar la experiencia de usuarios.
Podemos pensar en @defer
como el setTimeout() pero @defer
nos provee de más opciones y funcionalidades, por ejemplo:
setTimeout(() => {
console.log("Retrasado por 1 segundo.");
}, "1000");
Set timeout solo funciona en como un delay de componente usando @defer
con la novedad de que podemos mostrar un placeholder durante el tiempo que indiquemos en este caso un segundo.
@defer(on viewport(myPlaceholder), on timer(1s)) {
<app-child />
} @placeholder(minimum 1000ms) {
<div #myPlaceholder>...</div>
}
@defer
tiene más casos de usos, ya que además se incluye otras etiquetas que son de ayuda y que además son explícitas en su uso, como ser:
@placeholder
@error
-
@loading
Además de combinaciones porque podemos usar junto a un varios triggers(disparadores):
-
when isVisible
on idle
on inmediate
on interaction(trigger)
on timer(time)
on hover(trigger)
on viewport(container)
When
Es una condición que puede ser usada junto a una variable, una función, un valor que paso por un pipe o etc. Los Observables y AsyncPipes no pueden ser usados por el momento.
On idle:
Este es un comportamiento por defecto y se ejecuta cuando la app esté inactiva.
On immediate:
Este trigger se activa cuando él, témplate(plantilla) se renderiza.
On timer(1s):
Es un trigger basado en setTimeout el cual puede usarse en segundos usando la s o en milisegundos usando ms después de la cantidad
On interaction():
Al hacer clic en la platilla de referencia, precisamente en la referencia de plantilla #trigger como por ejemplo:
<button #trigger class="btn btn-red"> Botón de Acción <button/>
On hover(trigger):
Al hacer hover en la platilla de referencia, precisamente en la referencia de plantilla #triggerHover como por ejemplo:
Botón de Hover
On viewport(contenedor):
Al renderizar el viewport de la referencia #contenedor, por ejemplo la página se está renderizando, por lo que al llegar a la etiqueta #contenedor debe hacer algo o ejecutar una función.
Podemos usarlo todos a la vez simplemente separándolos por una coma de la siguiente manera:
@defer (when isVisible() && isAuth , prefetch on immediate; prefetch when isDataLoaded()) {
<componente-grande"/>
}
@placeholder (minimum 500ms){
Placeholder content!
}
@loading (minimum 1s; after 100ms){
Loading...
}
@error {
Loading failed :(
}
Por lo que podemos usar un defer que al retornar true que está visible y que esté autenticado isAuth
pre cargue inmediatamente cuando la plantilla esté lista y que pre cargue una función específica, la cual será isDataLoaded(); como puedes ver está el bloque @placeholder
el cual como su nombre lo indica nos sirve para poner contenido estático, @loading
en el cual podemos poner un skeleton loader o css de carga para que visualmente el usuario sepa que se está cargando y el @error
podemos utilizarlo para mostrar un mensaje o acciones.
Además, todo esto lo podemos combinar con el nuevo Control Flow
y combinarlo con @if
, @else
, @for
anidarlo, usar un @defer
y muchas combinaciones más para hacer de la experiencia algo más ameno.
defer y for:
@defer
dentro de un @for
@for (libro of libros) {
@defer {
<componente-grande />
}
}
@for
dentro de un @defer
@defer {
@for (libro of libros) {
<componente-grande />
}
}
En el primer ejemplo, por cada libro dentro del @for se creará una embedded view y una embedded view anidada por cada @defer
lo que nos dará la cantidad de libros.length * 2 que serían las embedded views del @for y libros.length en el @defer
por lo que podemos asumir que si tenemos 100 libros tendremos 100 * 2 + 100,
Ahora en el segundo ejemplo solo hay una interacción del @defer
por lo que las embedded view serán solo una y las del @for serán libros.legth + 1
Por lo que la decisión dependerá de como queremos resolver o usarlo y si cada uno de libros en el for contienen componentes grandes o queremos agregar interacción al @defer
como ser un loading o cualquiera de los ejemplos anteriores
Bonus
Como esto funciona en el compilador, pues simple:
@defer {
<componente-grande />
}
function defer_for_block {
return [ () => import('./componente-grande') ]
}
Esta solo es una de las muchas nuevas funcionalidades que trae el renacimiento de Angular
Top comments (0)