Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Чому велика реактивна форма Filament гальмує і як прискорити її без втрати логіки?

Кожне live()-поле після зміни робить запит на сервер, і за замовчуванням перерендерюється весь Livewire-компонент - вся форма з усіма секціями, повторювачами, опціями селектів. На формі з сотнею полів це сотні мілісекунд на кожну зміну, і інтерфейс відчувається «важким».

1. Перемальовувати лише те, що залежить від зміни:

TextInput::make('name')
    ->live(onBlur: true)
    ->partiallyRenderComponentsAfterStateUpdated(['email']);   // лише поле email

TextInput::make('quantity')
    ->live(debounce: 500)
    ->partiallyRenderAfterStateUpdated()                       // лише саме поле
    ->belowContent(fn (Get $get): string => 'Разом: ' . $get('quantity') * $get('price'));

2. Не рендерити взагалі, якщо потрібна лише серверна дія:

TextInput::make('search')
    ->live(debounce: 300)
    ->skipRenderAfterStateUpdated()
    ->afterStateUpdated(fn (?string $state) => /* записати в лог, кеш тощо */ null);

3. Перенести логіку в браузер - без запиту зовсім:

Select::make('role')
    ->options(['user' => 'Користувач', 'staff' => 'Персонал']);

Toggle::make('is_admin')
    ->hiddenJs(<<<'JS'
        $get('role') !== 'staff'
        JS);

TextInput::make('name')
    ->afterStateUpdatedJs(<<<'JS'
        $set('slug', ($state ?? '').toLowerCase().replaceAll(' ', '-'))
        JS);

hiddenJs(), visibleJs(), afterStateUpdatedJs() виконуються в Alpine на клієнті миттєво.

Безпека JS-варіантів: рядок з JavaScript виконується в браузері, тож ніколи не вставляйте в нього дані користувача конкатенацією - це XSS. Використовувати $state і $get() як значення безпечно.

4. Інші джерела повільності:

  • options() із запитом без кешу - перераховуються на кожному рендері. Для довгих списків - searchable() з getSearchResultsUsing();
  • Repeater на сотні елементів - кожен рендериться повністю. Тут краще relation manager;
  • важкі замикання у label(), helperText(), visible() - обчислюються на кожному рендері, зокрема запити в базу;
  • preload() великих зв'язків.

Як шукати вузьке місце: вкладка Network - розмір і час відповіді запиту livewire/update; Laravel Debugbar чи Telescope - запити в базу під час одного оновлення форми.

Докладніше в документації: Рендеринг полів

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання