主题
Defer
#[Defer] 属性使组件在初始页面加载完成后立即加载,防止慢速组件阻塞页面渲染。
基本用法
将 #[Defer] 属性应用到任何应该延迟加载的组件上:
php
<?php // resources/views/components/⚡revenue.blade.php
use Livewire\Attributes\Defer;
use Livewire\Component;
use App\Models\Transaction;
#[Defer] // [tl! highlight]
new class extends Component
{
public $amount;
public function mount()
{
// 慢速数据库查询...
$this->amount = Transaction::monthToDate()->sum('amount');
}
};
?>
<div>
本月收入:{{ $amount }}
</div>使用 #[Defer],组件最初渲染为一个空的 <div></div>,然后在页面加载完成后立即加载——无需等待它进入视口。
Lazy 与 Defer 的区别
Livewire 提供两种延迟组件加载的方式:
- 延迟加载(
#[Lazy]) - 组件在视口中可见时加载(当用户滚动到它们时) - 推迟加载(
#[Defer]) - 组件在初始页面加载完成后立即加载
两者都可以防止慢速组件阻塞初始页面渲染,但它们在组件实际加载的时机上有所不同。
渲染占位符
默认情况下,Livewire 在组件加载前渲染一个空的 <div></div>。您可以使用 placeholder() 方法提供自定义占位符:
php
<?php // resources/views/components/⚡revenue.blade.php
use Livewire\Attributes\Defer;
use Livewire\Component;
use App\Models\Transaction;
#[Defer]
new class extends Component
{
public $amount;
public function mount()
{
$this->amount = Transaction::monthToDate()->sum('amount');
}
public function placeholder() // [tl! highlight:start]
{
return <<<'HTML'
<div>
<svg><!-- 加载旋转图标... --></svg>
</div>
HTML;
} // [tl! highlight:end]
};
?>
<div>
本月收入:{{ $amount }}
</div>用户将看到加载旋转图标,直到组件完全加载。
匹配占位符元素类型
如果占位符的根元素是 <div>,您的组件也必须使用 <div> 元素。
捆绑请求
默认情况下,推迟的组件通过独立的网络请求并行加载。要将多个推迟的组件捆绑到单个请求中,请使用 bundle 参数:
php
<?php // resources/views/components/⚡revenue.blade.php
use Livewire\Attributes\Defer;
use Livewire\Component;
#[Defer(bundle: true)] // [tl! highlight]
new class extends Component
{
// ...
};现在,如果页面上有十个 revenue 组件,所有十个都将通过单个捆绑网络请求加载,而不是十个并行请求。
替代方法
使用 defer 参数
除了使用属性外,您还可以使用 defer 参数推迟特定组件实例:
blade
<livewire:revenue defer />当您只想推迟组件的某些实例时,这很有用。
覆盖属性
如果组件有 #[Defer] 但您想在某些情况下立即加载它,您可以覆盖它:
blade
<livewire:revenue :defer="false" />何时使用
在以下情况下使用 #[Defer]:
- 组件包含会延迟页面加载的慢速操作(数据库查询、API 调用)
- 组件在初始页面加载时始终可见(如果它在首屏之下,请改用
#[Lazy]) - 您想通过更快地显示页面来提高感知性能
了解更多
有关延迟加载和推迟加载的完整文档,包括占位符和捆绑策略,请参阅延迟加载文档。