Введение: проблема, о которой вы не знали
Ваши Blade-компоненты медленнее, чем вы думаете. Не потому что вы написали плохой код — сам процесс рендеринга несёт накладные расходы, которые накапливаются с каждым вложенным компонентом.
Кнопка, которая рендерится за микросекунды в единичном экземпляре, становится реальным узким местом, когда вы выводите 500 таких кнопок на дашборде.
Кейлеб Порцио (создатель Livewire, Alpine.js и Flux UI) говорил об этой проблеме ещё на Laracon US 2025: даже кэшированные Blade-компоненты примерно в 10 раз медленнее чистого PHP.
В феврале 2026 года на Laravel Worldwide Meetup он запустил Laravel Blaze и продемонстрировал бенчмарк в реальном времени: 25 000 компонентов отрендерены менее чем за 17 мс.
Это и есть проблема, которую решает Blaze.
Что такое Laravel Blaze?
Laravel Blaze (пакет livewire/blaze) — это новый пакет от команды Livewire, который прекомпилирует Blade-компоненты в оптимизированные PHP-функции, полностью минуя стандартный pipeline рендеринга.
Ключевые факты
| Параметр | Значение |
|---|---|
| Пакет | livewire/blaze |
| Версия | v1.0.0 (beta) |
| Дата релиза | 24 февраля 2026 года |
| Анонс | Laracon US 2025 + Laravel Worldwide Meetup (февраль 2026) |
| Поддержка Laravel | 10, 11, 12 |
| Требования PHP | ^8.1 |
| Автор | Caleb Porzio (команда Livewire) |
Цифры из официального README
- 500 мс → 13 мс для 25 000 компонентов
- Снижение накладных расходов на 97%
Что Blaze делает (и чего НЕ делает)
Что оптимизирует Blaze
Blaze оптимизирует только pipeline рендеринга Blade-компонентов. Не ваши запросы к БД. Не API-вызовы. Не бизнес-логику.
Если страница тормозит из-за 2-секундного Eloquent-запроса — Blaze не поможет. Для этого нужны оптимизации на уровне базы данных.
Что именно оптимизируется
Каждый анонимный Blade-компонент проходит многоэтапный процесс:
- Поиск файла представления
- Разрешение props
- Слияние атрибутов
- Обработка слотов
- Компиляция шаблона
- Рендеринг вывода
Для одной кнопки это незаметно. Для таблицы данных с сотнями строк, каждая из которых содержит несколько вложенных компонентов? Вот тут миллисекунды и накапливаются.
Blaze заменяет весь этот pipeline на прямые вызовы PHP-функций. Шаблон компилируется один раз в оптимизированную функцию, и каждый последующий рендер просто вызывает эту функцию.
Важное ограничение
⚠️ Blaze работает ТОЛЬКО с анонимными Blade-компонентами.
Если вы используете класс-компоненты (с отдельным PHP-классом), Blaze их не оптимизирует.
Анонимные компоненты — это файлы .blade.php в resources/views/components без соответствующего класса.
Установка и базовая настройка
Шаг 1: Установка пакета
composer require livewire/blaze:^1.0@beta
Всё. Никаких конфигурационных файлов. Никакой регистрации сервис-провайдеров. Blaze автоматически обнаруживается и регистрируется.
Шаг 2: Очистка скомпилированных представлений
php artisan view:clear
Это заставит Blaze перекомпилировать всё с новым оптимизированным pipeline.
Шаг 3: Включение оптимизации
Есть два способа активировать Blaze для ваших компонентов.
Способ A: Директива @blaze для отдельных компонентов
Добавьте @blaze в начало любого компонента:
{{-- resources/views/components/button.blade.php --}}
@blaze
@props(['variant' => 'primary'])
<button type="button" class="btn btn-{{ $variant }}">
{{ $slot }}
</button>
Способ B: Оптимизация целых директорий
Зарегистрируйте директории в сервис-провайдере:
use LivewireBlazeBlaze;
public function boot(): void
{
Blaze::optimize()
->in(resource_path('views/components/ui'))
->in(resource_path('views/components/icons'));
}
Можно комбинировать оба подхода: начать с конкретных директорий и расширять покрытие по мере проверки совместимости.
Бонус для пользователей Flux UI
Если вы используете Flux UI (официальная библиотека компонентов Livewire), вам вообще ничего делать не нужно. Все подходящие Flux-компоненты уже помечены @blaze. Установите пакет — и ваши Flux-компоненты станут быстрее автоматически.
Три уровня оптимизации
Blaze предлагает три уровня оптимизации, каждый из которых progressively агрессивнее. Понимание различий критически важно, потому что выбор неправильного уровня для неподходящего компонента — это путь к багам.
Tier 1: Оптимизированный компилятор (по умолчанию)
Это то, что вы получаете «из коробки» при добавлении @blaze или использовании Blaze::optimize().
Что происходит: Blade-шаблоны компилируются в оптимизированные PHP-функции вместо стандартного pipeline рендеринга.
@blaze
@props(['variant' => 'primary'])
<button type="button" class="btn btn-{{ $variant }}">
{{ $slot }}
</button>
Характеристики:
| Параметр | Значение |
|---|---|
| Снижение overhead | До 97% |
| Уровень риска | Очень низкий |
| Совместимость | Почти полная с обычным Blade |
| Конфигурация | Не требуется |
Для чего подходит: Для всего. Начните здесь и оставайтесь здесь, если нет специфической причины идти дальше.
Tier 2: Мемоизация (opt-in)
Мемоизация кэширует вывод компонента. Если один и тот же компонент появляется на странице несколько раз с идентичными props — он рендерится один раз, а остальные используют кэшированный результат.
@blaze(memo: true)
@props(['name'])
<svg class="icon icon-{{ $name }}">
<use href="#icon-{{ $name }}" />
</svg>
Представьте дашборд с 200 статусными иконками. Без мемоизации каждый <x-icon name="check" /> проходит полный цикл рендеринга, хотя вывод идентичен. С мемоизацией — один рендер, остальные — попадания в кэш.
Важное ограничение: Мемоизация работает только на компонентах без слотов. Если ваш компонент принимает {{ $slot }}, memo не применится, потому что содержимое слота меняется для каждого использования.
Для чего подходит: Иконки, аватары, бейджи и любые компоненты, которые появляются много раз с одинаковыми props.
Tier 3: Compile-Time Folding (opt-in)
Это «ядерный вариант». И в смысле «экстремально мощный», и в смысле «обращаться с крайней осторожностью».
Folding пре-рендерит компонент во время компиляции и встраивает чистый HTML прямо в родительский шаблон. Компонент перестаёт существовать в runtime. Никакого вызова функции. Никакого разрешения переменных. Никаких накладных расходов вообще.
@blaze(fold: true)
@props(['variant' => 'primary'])
<button type="button" class="btn btn-{{ $variant }}">
{{ $slot }}
</button>
При использовании этой кнопки со статическими props:
<x-button variant="secondary">Save</x-button>
Blaze не рендерит компонент в runtime. Он буквально «запекает» вывод в ваш шаблон во время компиляции:
<button type="button" class="btn btn-secondary">Save</button>
Нулевая стоимость в runtime. Компонент просто становится HTML.
Но есть нюанс. Folding работает только когда Blaze может определить все значения во время компиляции. Если вы передаёте динамическую переменную:
<x-button :variant="$user->theme">Save</x-button>
Blaze не может свернуть это, потому что не знает, чему равен $user->theme во время компиляции. Он автоматически откатывается к функциональному компилятору (Tier 1). Никакой ошибки, никакого краша. Просто никакого преимущества folding.
| Параметр | Значение |
|---|---|
| Снижение overhead | Полная ликвидация runtime-накладных расходов |
| Уровень риска | Высокий |
| Требования | Все значения должны быть известны на этапе компиляции |
Для чего подходит: Только для компонентов, которые вы лично проверили на «чистоту» (см. следующий раздел).
Когда Blaze сломает ваше приложение
Автор документации Blaze включил множество предупреждений, и не зря. Folding — это функция, от которой люди будут в наибольшем восторге, и она же наиболее вероятно вызовет тонкие, трудно диагностируемые баги.
Тест на «чистоту»
Перед добавлением @blaze с folding задайте себе пять вопросов о компоненте:
- Работает ли одинаково для всех пользователей? (нет
@auth, нетauth()->user()) - Работает ли одинаково на каждом запросе? (нет
request(), нет@csrf) - Работает ли одинаково в любое время? (нет
now(), нетCarbon::now()) - Использует только переданные props? (нет
session(), нетconfig(), нет запросов к БД) - Все дочерние компоненты тоже foldable?
Если ответ «нет» хотя бы на один вопрос — не используйте folding для этого компонента.
Документация Blaze называет это ментальной моделью «чистой функции». Ваши @blaze-компоненты должны быть как чистые функции в программировании: одинаковый ввод всегда даёт одинаковый вывод, без побочных эффектов.
Коварные ошибки
Эти паттерны выглядят безобидно, но приведут к багам:
1. Config-значения, меняющиеся между окружениями
{{-- URL будет «запечён» во время компиляции --}}
@blaze
<a href="{{ config('app.url') }}/dashboard">
Dashboard
</a>
Если вы компилируете представления в продакшене, config('app.url') запекается с тем значением, которое было на момент компиляции. Если потом измените .env — ссылка не обновится, пока вы не очистите скомпилированные представления. Легко пропустить.
2. Компоненты с CSRF-токенами
{{-- НИКОГДА не используйте @blaze с формами, содержащими @csrf --}}
@blaze
<form method="POST">
@csrf
<button type="submit">Submit</button>
</form>
CSRF-токен меняется для каждой сессии. Folding запечёт один токен навсегда. Каждая отправка формы будет падать.
3. Зависимый от времени контент
@blaze
<footer>
© {{ date('Y') }} My Company
</footer>
1 января этот футер всё ещё будет показывать прошлый год, пока вы не очистите представления.
4. Компоненты с non-foldable детьми
@blaze
<div class="card">
<x-user-greeting /> {{-- Если этот использует auth(), родитель тоже сломается --}}
{{ $slot }}
</div>
Folding «заразен» в обратную сторону. Родитель не может безопасно свернуться, если любой из его хардкоженных детей зависит от runtime-состояния.
Что Blaze ловит (а что — нет)
Blaze пытается защитить вас. Он выбросит исключение, когда обнаружит использование глобального состояния вроде auth(), session() или request() внутри folded-компонента.
Но документация прямо говорит: он не может поймать всё. Паттерны вроде доступа к хелпер-функции, которая внутри делает запрос к БД, или использование Blade-директивы, которая разрешается в runtime, могут проскользнуть незамеченными.
💡 Правило: Если не уверены, безопасен ли компонент для folding — не складывайте его. Дефолтный Tier 1 компилятор уже даёт 97% снижения накладных расходов. Этого, скорее всего, достаточно.
Встроенный профайлер
Blaze поставляется с профайлером, который генерирует flame charts и детализацию времени по каждому компоненту. Это по-настоящему полезно для определения, какие компоненты выигрывают от оптимизации больше всего.
Включение профайлера
Blaze::debug();
Это добавляет debug-оверлей на ваши страницы с кнопкой «Open Profiler». Профайлер показывает каждый компонент, отрендеренный во время запроса, его длительность, глубину вложенности и применённую стратегию оптимизации (compiled, folded, memoized или стандартный Blade).
Важное замечание
Профайлер хранит данные в дефолтном кэше приложения. Убедитесь, что вы не используете array-драйвер кэша в разработке. Redis или file-based кэши работают нормально.
Правильный подход к Blaze
- Включите профайлер первым делом
- Определите самые «тяжёлые» компоненты
- Применяйте оптимизации стратегически, а не blanket-покрытием
@blazeвсего подряд
Blaze vs стандартная оптимизация производительности
Будем честны об ожиданиях. Blaze решает очень специфическую проблему: накладные расходы рендеринга Blade-компонентов. Для большинства Laravel-приложений это не основной bottleneck.
Если приложение тормозит, обычные подозреваемые остаются теми же:
- Запросы к базе данных
- Внешние API-вызовы
- Неоптимизированная загрузка ассетов
Где Blaze сияет
1. Компонентно-тяжёлые приложения
Если вы построили дизайн-систему с переиспользуемыми Blade-компонентами, или если вы запускаете админ-панель Filament со сложными табличными представлениями, рендерящими сотни компонентов на страницу — снижение накладных расходов реально значимо.
2. Livewire-приложения
Каждый Livewire ре-рендер триггерит рендеринг Blade-компонентов, поэтому снижение этих накладных расходов имеет компаундинг-эффект на интерактивность. Если вы рендерите сложные Livewire-таблицы или дашборды, Blaze может сделать разницу между отзывчивым и вялым интерфейсом.
Сравнение с альтернативами (2026)
Blaze vs Livewire
| Параметр | Blaze | Livewire |
|---|---|---|
| Назначение | Оптимизация рендеринга Blade | Реактивные UI без JS-фреймворков |
| Что оптимизирует | Только анонимные компоненты | Полный цикл запроса |
| Runtime-нагрузка | Минимальная | Есть (WebSocket/polling) |
| Совместимость | Работает внутри Livewire-views | Независим от Blaze |
Вердикт: Это не конкуренты. Blaze оптимизирует Blade-компоненты, которые Livewire использует внутри. Используйте вместе.
Blaze vs Inertia.js
| Параметр | Blaze | Inertia.js |
|---|---|---|
| Подход | Server-side рендеринг | SPA без API |
| JS-требования | Минимальные (Alpine.js) | Vue/React/Svelte |
| SEO | Из коробки | Требует SSR |
| Компоненты | Blade | JS-компоненты |
Вердикт: Разные парадигмы. Inertia — для SPA-опыта, Blaze — для оптимизации классического server-side рендеринга.
Blaze vs Filament
| Параметр | Blaze | Filament |
|---|---|---|
| Тип | Оптимизатор | Admin-фреймворк |
| Назначение | Ускорение Blade | Быстрое создание админки |
| Совместимость | Работает с Filament | Использует Blade внутри |
Вердикт: Filament-панели могут выиграть от Blaze, потому что они рендерят много Blade-компонентов.
Blaze vs Turbo (Hotwire)
| Параметр | Blaze | Turbo |
|---|---|---|
| Назначение | Оптимизация Blade | SPA-подобный опыт без JS |
| Технология | PHP-компиляция | JavaScript-перехват ссылок |
| Сложность | Низкая | Средняя |
Вердикт: Можно использовать вместе. Turbo для навигации, Blaze для быстрого рендеринга.
Практический пример: CRUD с Blaze
Допустим, у нас есть простая таблица пользователей с кнопками действий.
Без Blaze
{{-- resources/views/components/action-button.blade.php --}}
@props(['action', 'label', 'color' => 'blue'])
<button
type="button"
class="px-3 py-1 rounded bg-{{ $color }}-500 text-white"
onclick="{{ $action }}"
>
{{ $label }}
</button>
При рендеринге 100 пользователей с 3 кнопками на каждого = 300 компонентов. Каждый проходит полный pipeline.
С Blaze (Tier 1)
{{-- resources/views/components/action-button.blade.php --}}
@blaze
@props(['action', 'label', 'color' => 'blue'])
<button
type="button"
class="px-3 py-1 rounded bg-{{ $color }}-500 text-white"
onclick="{{ $action }}"
>
{{ $label }}
</button>
Одна строка @blaze — и 300 компонентов рендерятся через оптимизированные функции.
С Blaze + мемоизация (для иконок)
{{-- resources/views/components/icon.blade.php --}}
@blaze(memo: true)
@props(['name', 'size' => 'md'])
<svg class="icon icon-{{ $name }} icon-{{ $size }}">
<use href="#icon-{{ $name }}" />
</svg>
Если все 100 пользователей показывают одну и ту же иконку «edit» — рендерится один раз, 99 раз берётся из кэша.
Рекомендации
Что делать
✅ Установите пакет. Tier 1 компилятор достаточно безопасен почти для любого проекта. Соотношение риск/награда сильно перевешивает в сторону награды.
✅ Начните только с Tier 1. Не прыгайте сразу в folding. 97% снижения накладных расходов от оптимизированного компилятора уже значимы.
✅ Используйте мемоизацию выборочно. Если профайлер показывает компонент, рендерящийся десятки раз с идентичными props (иконки — классический пример), добавьте memo: true. Но не включайте его blanket.
✅ Тестируйте в staging. Пакет помечен как early-stage beta (v1.0.0@beta). API может меняться, есть edge cases, которые ещё прорабатываются.
Чего НЕ делать
❌ Не используйте folding без проверки. Только fold-компоненты, которые вы лично проверили на «чистоту». Когда сомневаетесь — skip.
❌ Не применяйте @blaze к формам с @csrf. Это сломает отправку форм.
❌ Не ожидайте miracles от медленных запросов. Blaze не ускорит ваши Eloquent-запросы.
❌ Не используйте array-кэш с профайлером. Данные не сохранятся между запросами.
FAQ
Работает ли Blaze с Livewire-компонентами?
Blaze специально разработан для анонимных Blade-компонентов, не для Livewire-компонентов напрямую. Но поскольку Livewire-компоненты рендерят Blade-шаблоны внутри, оптимизация Blade-компонентов в ваших Livewire-views положительно влияет на общую производительность Livewire.
Будет ли Blaze конфликтовать с моим текущим Blade-setup?
Нет. Tier 1 компилятор — это drop-in замена, которая поддерживает feature parity со стандартным Blade. Если возникнут проблемы, можно убрать директиву @blaze или удалить пакет целиком — всё вернётся к норме.
Как понять, что Blaze реально помогает моему приложению?
Используйте встроенный профайлер (Blaze::debug()). Он показывает timing по каждому компоненту и применённую стратегию оптимизации. Сравните времена рендеринга с Blaze и без, чтобы измерить реальный impact на ваше конкретное приложение.
Работает ли Blaze с Laravel 10?
Да. Blaze поддерживает Laravel 10, 11 и 12 и требует PHP 8.1 или выше.
Можно ли использовать Blaze в продакшене?
Tier 1 оптимизированный компилятор безопасен для продакшена. Пакет помечен как beta, но основная стратегия компиляции хорошо протестирована. Folding (Tier 3) требует более тщательной валидации перед деплоем в прод. Всегда тестируйте тщательно в staging-окружении.
Заключение
Blaze решает проблему, о которой большинство Laravel-разработчиков даже не знали. Накладные расходы рендеринга Blade-компонентов невидимы, пока у вас не станет достаточно компонентов, чтобы это стало заметно — и к тому моменту вы обычно вините что-то другое.
То, что это one-line install с немедленными преимуществами (Tier 1) и опциональными продвинутыми функциями (мемоизация, folding) для случаев, когда они нужны — делает его лёгкой рекомендацией.
Просто не слишком увлекайтесь folding, пока не поймёте все его последствия.
Если вы строите что-то компонентно-тяжёлое и производительность важна — попробуйте Blaze. Это один из тех редких пакетов, который даёт реальный прирост производительности практически бесплатно.
Резюме в одной таблице
| Уровень | Команда | Снижение overhead | Риск | Когда использовать |
|---|---|---|---|---|
| Tier 1 | @blaze |
До 97% | Низкий | Всегда, для всех анонимных компонентов |
| Tier 2 | @blaze(memo: true) |
Кэширование идентичных | Низкий | Иконки, бейджи — компоненты без слотов |
| Tier 3 | @blaze(fold: true) |
100% (нулевой runtime) | Высокий | Только проверенные «чистые» компоненты |