Blazing Fast Blade: Optimizing Laravel Component Rendering with Caleb Porzio
Overview
is a high-performance compiler designed to eliminate the rendering overhead that plagues modern, component-heavy applications. As developers move away from global styles toward granular components, the number of components on a single page has exploded. A typical dashboard might render thousands of nested components, leading to server-side bottlenecks where rendering alone takes hundreds of milliseconds or even seconds.
developed to solve this specifically for the UI library, though it works with any anonymous component. By utilizing advanced compiler techniques like memoization and code folding, Blaze can reduce rendering times by over 90%, turning a 1.5-second render into a 6-millisecond flash. It accomplishes this by bypassing the heavy lifting 's core engine usually performs—such as container lookups and view resolution—and transforming components into highly optimized functions.
Prerequisites
To get the most out of this tutorial, you should have a solid foundation in the following:
- Laravel Basics: Understanding the request lifecycle and service providers.
- Blade Components: Familiarity with anonymous components, props, and slots.
- PHP Performance Concepts: A basic understanding of how
opcacheworks and why file system lookups are expensive compared to in-memory operations. - Composer: Ability to manage packages via the dependency manager.
Key Libraries & Tools
- : The core package that provides the optimized compiler and optimization directives.
- : While not strictly required, Blaze is built by the team and integrates seamlessly with its reactive patterns.
- : A UI component library that heavily utilizes Blaze to maintain high performance despite its complex structure.
- The Blaze Profiler: A built-in debugging tool that visualizes component render times and folding status.
Code Walkthrough: Implementing Blaze
Installation and Basic Setup
First, pull the package into your project using . Although it is developed by the team, it is a standalone package.
composer require livewire/blaze
Once installed, you must opt-in your components to the Blaze compiler. You do this by adding the @blaze directive at the very top of your component file.
{{-- resources/views/components/button.blade.php --}}
@blaze
<button {{ $attributes }}>
{{ $slot }}
</button>
When you add @blaze, the package intercepts the standard compilation. Instead of generating a file that performs dozens of app()->make() and view()->exists() calls at runtime, Blaze generates a plain function. This function accepts props and slots as arguments and returns a string, bypassing the overhead of the Container entirely.
Level 2: Component Memoization
If your page renders the same component multiple times with the exact same attributes (like a status badge or a specific icon), you can enable memoization. This caches the rendered HTML in memory during a single request.
{{-- resources/views/components/status-pill.blade.php --}}
@blaze
@memo(true)
<span class="pill-{{ $type }}">
{{ $label }}
</span>
By adding @memo(true), Blaze creates a static cache key based on the component name and the serialized props. If you render this component 500 times with the same type and label, only executes the logic once. The other 499 instances are simple string lookups from an internal array.
Level 3: Code Folding and Partial Folding
The most aggressive optimization is Code Folding. This attempts to "pre-render" the component at compile time rather than runtime. If a component is entirely static, Blaze replaces the component call in your parent view with the actual HTML string during the compilation phase.
{{-- resources/views/components/icon.blade.php --}}
@blaze
@fold(true)
<svg ...> ... </svg>
When Blaze sees this icon in a parent view, it executes the logic once, takes the resulting HTML, and hardcodes that HTML into the cached file. This effectively deletes the component's runtime cost.
For components with dynamic parts, Blaze uses Partial Folding. It uses a tokenized parser to identify dynamic variables, replaces them with placeholders, renders the static shell, and then re-inserts the dynamic logic into the resulting string. This allows for nearly static performance even when passing a dynamic $label to a button.
Syntax Notes: The Tokenized Parser
Unlike standard , which uses to find and replace tags, Blaze utilizes a custom Tokenized Parser.
- Tokenization: It breaks the source code into a flat list of tokens (Tag Open, Tag Name, Attribute, String, Variable).
- AST Construction: It assembles these tokens into an Abstract Syntax Tree (AST). This tree understands that a
flux:buttoncontains aflux:iconas a child. - Transformation: Blaze traverses the AST. If it finds a component marked for folding, it executes the render logic.
- Code Generation: It spits out the final, optimized file.
This structured approach is what allows Blaze to "know" which parts of a component are safe to hardcode and which must remain dynamic.
Practical Examples: Boosting a Dashboard
Consider a dashboard with 1,000 table rows, each containing an avatar, a status badge, and an action dropdown.
- Without Blaze: performs 3,000+ container lookups and merges thousands of attribute bags. This can easily take 150-200ms.
- With Blaze + Memoization: The avatar and status badge (often repeated) are memoized. The action dropdown is optimized into a function call. Total render time drops to ~15ms.
- With Blaze + Folding: The SVG icons within the dropdown are folded away. They no longer exist as logic at runtime. Total render time drops to <10ms.
Tips & Gotchas
- Static vs. Dynamic State: Code folding is a "sharp knife." If your component relies on global state (like
auth()->user()) but you don't pass that state as a prop, the component might fold based on the user who triggered the compilation. Always ensure folded components are pure functions of their props. - The Profiler: Use
BLAZE_DEBUG=truein your.env. This adds a floating button to your UI that breaks down exactly how many milliseconds each component took and why it was (or wasn't) folded. - The @unblaze Directive: If you have a specific block within a blazified component that must remain dynamic and escape the optimized compiler's logic, wrap it in
@unblaze. This is useful for validation errors or CSRF tokens that must be unique per render. - Anonymous Only: Currently, Blaze only optimizes anonymous components. Class-based components are not yet supported due to the complexity of their lifecycles and constructor logic.
- 20%· products
- 18%· products
- 15%· companies
- 8%· products
- 8%· products
- Other topics
- 33%

Laravel Worldwide Meetup - Blaze Demo + Launch Party
WatchLaravel // 1:21:52
The official YouTube channel of Laravel, the clean stack for Artisans and agents. We will update you on what's new in the world of Laravel, from the framework to our products Cloud, Forge, and Nightwatch.