Optimización en Livewire: Evitando el desbordamiento de payload con consultas directas a la base de datos

En el proyecto Reimpact/platform, nos enfrentamos a un desafío común al trabajar con Livewire y grandes volúmenes de datos: el desbordamiento del payload. Específicamente, en la gestión de listados de productos, el array matches que se almacenaba en el estado de un componente Livewire excedía el límite de 1MB para el payload, especialmente en entornos con una gran cantidad de productos asociados a cada inquilino.

Este problema no solo provocaba errores en la interfaz de usuario, sino que también degradaba significativamente la experiencia del usuario debido a la lentitud en la carga y la inestabilidad del componente.

La Solución: Consultas Directas a la Base de Datos

Para resolver este cuello de botella, se implementó una estrategia clave: en lugar de almacenar el array matches completo en el estado del componente Livewire, ahora se consulta directamente la base de datos en cada renderizado. Esta aproximación reduce drásticamente el tamaño del estado del componente, ya que solo se transmiten los datos necesarios para la vista actual, y no el dataset completo en cada ciclo de vida.

Consideremos un ejemplo simplificado de cómo se podría pasar de un estado con un array grande a una propiedad computada que consulta la base de datos:

Antes (almacenando en el estado):

class ListProducts extends Component
{
    public $matches;

    public function mount()
    {
        // Esto se almacena en el estado de Livewire
        $this->matches = ProductMatch::query()
                                    ->where('tenant_id', auth()->id())
                                    ->get()
                                    ->toArray();
    }

    public function render()
    {
        return view('livewire.list-products', ['matches' => $this->matches]);
    }
}

Después (consultando directamente con una propiedad computada):

class ListProducts extends Component
{
    // Otros datos de estado, pero 'matches' ya no es público

    public function getMatchesProperty()
    {
        // La consulta se ejecuta en cada renderizado, no se almacena en el estado
        return ProductMatch::query()
                                    ->where('tenant_id', auth()->id())
                                    ->get();
    }

    public function render()
    {
        return view('livewire.list-products', ['matches' => $this->matches]);
    }
}

Esta refactorización asegura que el componente Livewire se mantenga ligero y reactivo, independientemente del volumen de datos subyacentes.

Mejoras Adicionales

Junto con la optimización del payload, se implementaron otras mejoras significativas para la experiencia del usuario y la funcionalidad:

  • Eliminación de Widgets de Métricas de Producto: Los widgets de métricas de producto fueron removidos de la vista ListProducts, dedicándolos ahora a una página exclusiva. Esto mejora la claridad y el rendimiento de la lista principal.
  • Filtros Avanzados: Se añadieron nuevos filtros a la tabla matches, incluyendo un filtro por nivel y filtros por marca y categoría. Esto permite a los usuarios refinar sus búsquedas de manera más precisa.
  • Tabla con Encabezado Fijo y Scroll: La tabla ahora cuenta con un encabezado fijo (sticky header) y se puede desplazar verticalmente con una altura máxima de 600px, mejorando la usabilidad y la visualización de grandes conjuntos de datos.

Estas optimizaciones en la platforma Reimpact demuestran un compromiso con la escalabilidad y la eficiencia, asegurando que los usuarios puedan interactuar con la aplicación de manera fluida y sin interrupciones, incluso con crecientes volúmenes de información.

Optimización en Livewire: Evitando el desbordamiento de payload con consultas directas a la base de datos
Gerardo Ruiz

Gerardo Ruiz

Author

Share: