Laravel: 我应该在循环中使用@include 吗?
Laravel: should i use @include inside loops?
下面我提供了两个循环显示产品卡片的例子。第一个在我看来更方便,但由于循环内的这个@include,我担心性能。由于这个任务很常见,我想选择最好的方法。
案例 1. 使用 @include:
search.blade.php
<div id='search-results'>
@foreach($items as $item)
@include('items._item')
@endforeach
</div>
_item.blade.php
<div>
<div class='item-title'>{{$item->title}}</div>
<div class='item-description'>{{$item->description}}</div>
</div>
情况 2. 没有 @include:
search.blade.php
<div id='search-results'>
@include('items._items_list')
</div>
_items_list.blade.php
@foreach($items as $item)
<div class='item-title'>{{$item->title}}</div>
<div class='item-description'>{{$item->description}}</div>
@endforeach
第一种方法似乎是最正确的方法。
这可能会造成巨大的性能问题。当您像第一种情况一样循环 @include
时,生成的原始 php 文件确实将包含的视图作为函数调用。这会稍微减慢页面呈现速度。
第二种情况性能更高,因为它基本上是 1 个包含(带有一个包含 html 片段的循环)。
我现在遇到了这个问题。我有一个循环 250 条记录的数据表,但每条记录包含 5 个助手。在我的例子中,这些助手非常重要并且包含一些必要的(简单的)逻辑,但即使有简单的逻辑,1250 个子视图也会导致性能大幅下降,将页面的加载时间减少到 5-6 秒,而复制时为 300-400 毫秒在这个帮助代码上。
我正在努力编写一个 Laravel 扩展来解析所有 @include
并将其替换为实际代码,但这不是一件容易的事...
示例 1:查看 blade 如何解析您的 @foreach
循环
考虑一下这个非常简单的 foreach 循环。它只是在每个元素的 <h1>
标签中输出 object 的 name
:
@foreach($paymentMethods as $paymentMethod)
<h1>{{ $paymentMethod->name }}</h1>
@endforeach
可以看到storage/framework/views/*.php
里面生成的数据出来有点复杂:
<?php $__currentLoopData = $paymentMethods; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $paymentMethod): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<h3>
<?php echo e($paymentMethod->name);
</h3>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
<?php /**PATH C:\xampp\sites\someproject\resources\views/payment_providers.blade.php ENDPATH**/ ?>
正在调用来自 $__env
object 的各种助手。例如,这些将为您的 @foreach
循环添加额外的功能,例如 $loop->first
/$loop->last
变量(参见 https://laravel.com/docs/5.8/blade)。
示例 2:@include
语句
@include('myhelper')
<?php echo $__env->make('myhelper', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?>
$__env->make()
函数解析为 vendor/laravel/framework/src/Illuminate/View/Factory.php
,它计算您的 blade 助手。这个过程包括查找视图文件本身,通过 blade 引擎再次解析它,调度事件...
Blade 快捷方式无疑会对性能产生影响。这仅取决于您使用的数量以及是否值得为您多花几毫秒。
恕我直言,如果您碰巧需要循环大 collections 并使用许多 @include
语句,那么这对生产环境来说是一个非常值得的优化。然后我建议使用标准的 <?php foreach($arr as $item): ?>
/<?php endforeach ?>
语法,结合一些简单的 php 函数,如果你需要 return html re-useable html 件.
我通过使用传递给某些 blade 的 75 行然后迭代这 75 行两次来测试此行为。
第一个仅使用此 blade 文件中的 blade 代码,另一个调用 @include 另一个具有相同代码的 blade 文件并使用 microtime(true) php 在每次刺激的开始和结束时起作用
如果使用@include.
,时间增加了 3 倍
下面我提供了两个循环显示产品卡片的例子。第一个在我看来更方便,但由于循环内的这个@include,我担心性能。由于这个任务很常见,我想选择最好的方法。
案例 1. 使用 @include:
search.blade.php
<div id='search-results'>
@foreach($items as $item)
@include('items._item')
@endforeach
</div>
_item.blade.php
<div>
<div class='item-title'>{{$item->title}}</div>
<div class='item-description'>{{$item->description}}</div>
</div>
情况 2. 没有 @include:
search.blade.php
<div id='search-results'>
@include('items._items_list')
</div>
_items_list.blade.php
@foreach($items as $item)
<div class='item-title'>{{$item->title}}</div>
<div class='item-description'>{{$item->description}}</div>
@endforeach
第一种方法似乎是最正确的方法。
这可能会造成巨大的性能问题。当您像第一种情况一样循环 @include
时,生成的原始 php 文件确实将包含的视图作为函数调用。这会稍微减慢页面呈现速度。
第二种情况性能更高,因为它基本上是 1 个包含(带有一个包含 html 片段的循环)。
我现在遇到了这个问题。我有一个循环 250 条记录的数据表,但每条记录包含 5 个助手。在我的例子中,这些助手非常重要并且包含一些必要的(简单的)逻辑,但即使有简单的逻辑,1250 个子视图也会导致性能大幅下降,将页面的加载时间减少到 5-6 秒,而复制时为 300-400 毫秒在这个帮助代码上。
我正在努力编写一个 Laravel 扩展来解析所有 @include
并将其替换为实际代码,但这不是一件容易的事...
示例 1:查看 blade 如何解析您的 @foreach
循环
考虑一下这个非常简单的 foreach 循环。它只是在每个元素的 <h1>
标签中输出 object 的 name
:
@foreach($paymentMethods as $paymentMethod)
<h1>{{ $paymentMethod->name }}</h1>
@endforeach
可以看到storage/framework/views/*.php
里面生成的数据出来有点复杂:
<?php $__currentLoopData = $paymentMethods; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $paymentMethod): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<h3>
<?php echo e($paymentMethod->name);
</h3>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
<?php /**PATH C:\xampp\sites\someproject\resources\views/payment_providers.blade.php ENDPATH**/ ?>
正在调用来自 $__env
object 的各种助手。例如,这些将为您的 @foreach
循环添加额外的功能,例如 $loop->first
/$loop->last
变量(参见 https://laravel.com/docs/5.8/blade)。
示例 2:@include
语句
@include('myhelper')
<?php echo $__env->make('myhelper', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?>
$__env->make()
函数解析为 vendor/laravel/framework/src/Illuminate/View/Factory.php
,它计算您的 blade 助手。这个过程包括查找视图文件本身,通过 blade 引擎再次解析它,调度事件...
Blade 快捷方式无疑会对性能产生影响。这仅取决于您使用的数量以及是否值得为您多花几毫秒。
恕我直言,如果您碰巧需要循环大 collections 并使用许多 @include
语句,那么这对生产环境来说是一个非常值得的优化。然后我建议使用标准的 <?php foreach($arr as $item): ?>
/<?php endforeach ?>
语法,结合一些简单的 php 函数,如果你需要 return html re-useable html 件.
我通过使用传递给某些 blade 的 75 行然后迭代这 75 行两次来测试此行为。 第一个仅使用此 blade 文件中的 blade 代码,另一个调用 @include 另一个具有相同代码的 blade 文件并使用 microtime(true) php 在每次刺激的开始和结束时起作用 如果使用@include.
,时间增加了 3 倍