Rendimiento
SWR proporciona una funcionalidad crítica en todo tipo de aplicaciónes web, por lo que el rendimiento es una prioridad absoluta.
SWR’s tiene caché incorporado y la deduplicación evitan las solicitudes de red innecesarias,
pero el rendimiento del propio hook useSWR
sigue siendo importante. En una aplicación compleja, puede haber cientos de llamadas useSWR
en una solo página.
SWR asegura que su aplicación tiene:
- no hay peticiones de red innecesarias
- no hay renderizado innecesarios
- no se importa código innecesario
sin ningún cambio de código por su parte.
Deduplicación
Es muy común reutilizar los hooks SWR en tu aplicación. Por ejemplo, una aplicación que muestra el avatar del usuario actual 5 veces:
function useUser() {
return useSWR('/api/user', fetcher)
}
function Avatar () {
const { data, error } = useUser()
if (error) return <Error />
if (!data) return <Spinner />
return <img src={data.avatar_url} />
}
function App() {
return <>
<Avatar />
<Avatar />
<Avatar />
<Avatar />
<Avatar />
</>
}
Cada componente <Avatar/>
tiene un hook useSWR
en su interior. Dado que tienen el mismo key SWR y
que se renderizan casi al mismo tiempo, sólo se hará 1 solicitud de red.
Se pueden reutilizar los hooks de datos (como useUser
en el ejemplo anterior) en todas partes, sin preocuparse por el rendimiento
o las peticiones duplicadas.
También existe la opción dedupingInterval
para anular el intervalo de deduplicación por defecto.
Comparación profunda
SWR por defecto tiene deep compares al cambio de datos. Si el valor de data
no ha cambiado, no se
activará una nueva renderización.
También puede personalizar la función de comparación mediante la opción compare
si quieres cambiar el comportamiento.
Por ejemplo, algunas respuestas de la API devuelven una marca de tiempo del servidor que tal vez quiera excluir de la difusión de datos.
Colección de dependencias
useSWR
devuelve 4 valores de estado: data
, error
, isLoading
y isValidating
cada uno de ellos puede actualizarse de forma independientemente.
Por ejemplo, si imprimimos esos valores dentro de un ciclo de vida completo de obtención de datos, será algo como esto:
function App () {
const { data, error, isLoading, isValidating } = useSWR('/api', fetcher)
console.log(data, error, isLoading, isValidating)
return null
}
En el peor de los casos (si la primera solicitud falló, entonces el reintento fue exitoso). Se verán 4 líneas de registros:
// console.log(data, error, isLoading, isValidating)
undefined undefined true true // => start fetching
undefined Error false false // => end fetching, got an error
undefined Error true true // => start retrying
Data undefined false false // => end retrying, get the data
Los cambios de estado tienen sentido. Pero eso también significa que nuestro componente se renderizo 4 veces.
Si cambiamos nuestro componente para usar solo data
:
function App () {
const { data } = useSWR('/api', fetcher)
console.log(data)
return null
}
La magia ocurre - ahora solo hay 2 rederizaciones:
// console.log(data)
undefined // => hydration / initial render
Data // => end retrying, get the data
El mismo proceso ha ocurrido internamente, hubo un error de la primera solicitud, entonces tenemos los datos del reintento.
Sin embargo, SWR sólo actualiza los estados que utiliza el componente, que ahora sólo es data
.
Si no se utilizan siempre estos 3 estados, ya se está beneficiando de esta función. En Vercel (opens in a new tab), esta optimización se traduce en un 60% menos de repeticiones.
Tree Shaking
El paquete SWR es tree-shakeable (opens in a new tab) y no tiene efectos secundarios.
Esto significa que si sólo se importa useSWR
core API, las APIs no utilizadas, como useSWRInfinite
, no se incluirán en la aplicación.