Julian Beaujardin
Julian Beaujardin July 16th, 2024

Muchas aplicaciones web modernas se construyen como "aplicaciones de una sola página" (SPA). En estas aplicaciones, cada página renderizada por la aplicación ya no requiere una recarga completa de la página del navegador, evitando la sobrecarga de volver a descargar los activos de JavaScript y CSS en cada solicitud.

La alternativa a una aplicación de una sola página es una aplicación de múltiples páginas. En estas aplicaciones, cada vez que un usuario hace clic en un enlace, se solicita y renderiza una página HTML completamente nueva en el navegador.

Mientras que la mayoría de las aplicaciones PHP han sido tradicionalmente aplicaciones de múltiples páginas, Livewire ofrece una experiencia de aplicación de una sola página a través de un simple atributo que puedes añadir a los enlaces en tu aplicación: wire:navigate.

Uso básico

Vamos a explorar un ejemplo de uso de wire:navigate. A continuación se muestra un archivo típico de rutas de Laravel (routes/web.php) con tres componentes Livewire definidos como rutas:

use App\Livewire\Dashboard;
use App\Livewire\ShowPosts;
use App\Livewire\ShowUsers;

Route::get('/', Dashboard::class);
Route::get('/posts', ShowPosts::class);
Route::get('/users', ShowUsers::class);

Al agregar wire:navigate a cada enlace en un menú de navegación en cada página, Livewire evitará el manejo estándar del clic en el enlace y lo reemplazará con su propia versión más rápida:

<nav>
    <a href="/" wire:navigate>Dashboard</a>
    <a href="/posts" wire:navigate>Posts</a>
    <a href="/users" wire:navigate>Users</a>
</nav>

A continuación, se muestra un desglose de lo que ocurre cuando se hace clic en un enlace wire:navigate:

  • El usuario hace clic en un enlace.
  • Livewire evita que el navegador visite la nueva página.
  • En su lugar, Livewire solicita la página en segundo plano y muestra una barra de carga en la parte superior de la página.
  • Cuando se recibe el HTML de la nueva página, Livewire reemplaza la URL, la etiqueta <title> y el contenido del <body> de la página actual con los elementos de la nueva página.

Esta técnica resulta en tiempos de carga de página mucho más rápidos, a menudo el doble de rápido, y hace que la aplicación "se sienta" como una aplicación de una sola página impulsada por JavaScript.

Redirecciones

Cuando uno de tus componentes Livewire redirige a los usuarios a otra URL dentro de tu aplicación, también puedes instruir a Livewire para que use su funcionalidad wire:navigate para cargar la nueva página. Para lograr esto, proporciona el argumento navigate al método redirect():

Ahora, en lugar de que se use una solicitud de página completa para redirigir al usuario a la nueva URL, Livewire reemplazará el contenido y la URL de la página actual con la nueva.

Prefetching de enlaces

Por defecto, Livewire incluye una estrategia suave para precargar páginas antes de que un usuario haga clic en un enlace:

  • Un usuario presiona el botón del mouse.
  • Livewire comienza a solicitar la página.
  • Levantan el botón del mouse para completar el clic.
  • Livewire termina la solicitud y navega a la nueva página.

Sorprendentemente, el tiempo entre que un usuario presiona y levanta el botón del mouse suele ser suficiente para cargar la mitad o incluso toda una página del servidor.

Si deseas un enfoque aún más agresivo para la precarga, puedes usar el modificador .hover en un enlace:

<a href="/posts" wire:navigate.hover>Posts</a>

El modificador .hover instruirá a Livewire para que precargue la página después de que un usuario haya pasado el mouse sobre el enlace durante 60 milisegundos.

La precarga al pasar el mouse aumenta el uso del servidor

Debido a que no todos los usuarios harán clic en un enlace sobre el que pasan el mouse, agregar .hover solicitará páginas que pueden no ser necesarias, aunque Livewire intenta mitigar parte de esta sobrecarga esperando 60 milisegundos antes de precargar la página.

Persistencia de elementos entre visitas a páginas

A veces, hay partes de una interfaz de usuario que necesitas persistir entre cargas de página, como reproductores de audio o video. Por ejemplo, en una aplicación de podcasts, un usuario puede querer seguir escuchando un episodio mientras navega por otras páginas.

Puedes lograr esto en Livewire con la directiva @persist.

Al envolver un elemento con @persist y proporcionarle un nombre, cuando se solicita una nueva página usando wire:navigate, Livewire buscará un elemento en la nueva página que tenga un @persist coincidente. En lugar de reemplazar el elemento como de costumbre, Livewire usará el elemento del DOM existente de la página anterior en la nueva página, preservando cualquier estado dentro del elemento.

Aquí hay un ejemplo de un elemento <audio> siendo persistido entre páginas usando @persist:

@persist('player')
    <audio src="{{ $episode->file }}" controls></audio>
@endpersist

Si el HTML anterior aparece en ambas páginas — la página actual y la siguiente — el elemento original se reutilizará en la nueva página. En el caso de un reproductor de audio, la reproducción de audio no se interrumpirá al navegar de una página a otra.

Ten en cuenta que el elemento persistente debe colocarse fuera de tus componentes Livewire. Una práctica común es colocar el elemento persistente en tu diseño principal, como resources/views/components/layouts/app.blade.php.

Preservar la posición de desplazamiento

Por defecto, Livewire preservará la posición de desplazamiento de una página al navegar hacia adelante y hacia atrás entre páginas. Sin embargo, a veces puedes querer preservar la posición de desplazamiento de un elemento individual que estás persistiendo entre cargas de página.

Para hacer esto, debes agregar wire:scroll al elemento que contiene una barra de desplazamiento, así:

@persist('scrollbar')
<div class="overflow-y-scroll" wire:scroll>
    <!-- ... -->
</div>
@endpersist

Uso con software de análisis

Al navegar entre páginas usando wire:navigate en tu aplicación, cualquier etiqueta <script> en el <head> solo se evalúa cuando se carga inicialmente la página.

Esto crea un problema para el software de análisis como Fathom Analytics. Estas herramientas dependen de un fragmento <script> que se evalúa en cada cambio de página, no solo en el primero.

Herramientas como Google Analytics son lo suficientemente inteligentes como para manejar esto automáticamente, sin embargo, cuando usas Fathom Analytics, debes agregar data-spa="auto" a tu etiqueta de script para asegurar que cada visita a la página se rastree correctamente:

<head>
    <!-- ... -->

    <!-- Fathom Analytics -->
    @if (! config('app.debug'))
        <script src="https://cdn.usefathom.com/script.js" data-site="ABCDEFG" data-spa="auto" defer></script>
    @endif
</head>

Evaluación de scripts

Al navegar a una nueva página usando wire:navigate, parece que el navegador ha cambiado de página; sin embargo, desde la perspectiva del navegador, técnicamente todavía estás en la página original.

Debido a esto, los estilos y scripts se ejecutan normalmente en la primera página, pero en las páginas siguientes, es posible que tengas que ajustar la forma en que normalmente escribes JavaScript.