Кожне 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 - запити в базу під час одного оновлення форми.