I have a performance issue with Livewire, when i use many times the same component. I already had this issue in the past, and each time I managed this issue by switching off the framework and use Vuejs/api directly. Maybe I do not use Livewire correctly ... or maybe I missed something somewhere.
Question: How to manage the Livewire usage of many identical components with parameters and model data, without exploding the rendering time and explode the performance ? Did I miss something ? Any tips ?
Thanks in advance.
Issue:
I have a webpage with several hundreds of entries. For each of them, i call a Livewire component. For 105 components, the page take 8-11 seconds to load.
I used debugbar, and discover that the render livewire function is very very consuming (8.29s) comparing to the application time to (8.46). I audited the functions inside, and it's only 205.53ms. Ok, 400ms if we take the part that fetch the data.
The conclusion i got after some reading, is that the root cause is the Lazy Loading of models. And indeed, I use two models (User & Item) on my component:
<livewire:matrix-power-slider-resume-group :type="$type" :user="$user" :item="$item" aspect="T"></livewire:matrix-power-slider-resume-group>
User & Item have of course some relationships, but when I debug them the relationships are not loaded/used (mean I should have a little serialized 'json' object). So I don't suspect the big-lazy-model-loading issue.
I tried to pass the IDs instead of the model, and ask to my component to get again the data. But here, I explode the number of queries (120 with model in parameters versus +1800 with IDs), and I still have very bad performances (7-11s) due to the number of queries.
I used a debug measure before the html <livewire:... /> code, and this is this part that consume all the time. Not the render() function of the component, not the mount(), but the livewire render from the blade file :(
I also tried to use the model declaration in the class:
public function mount($type, $userId, $itemId, $aspect = null, User $user = null, item $item = null)
or not:
public function mount($type, $userId, $itemId, $aspect = null, $user = null, $item = null)
Code:
<?php
namespace App\Http\Livewire;
use App\Models\Matrix\Item;
use App\Models\User;
use Livewire\Component;
class MatrixPowerSliderRange extends Component
{
public $type;
public $userId;
public $user;
public $itemId;
public $item;
public $aspect;
public $value; // data used into component
public function mount($type, $userId, $itemId, $aspect = null, User $user = null, Item $item = null)
{
$this->type = $type;
$this->itemId = $itemId;
$this->item = $item;
$this->userId = $userId;
$this->user = $user;
$this->aspect = $aspect;
}
public function load()
{
// Fetch data if only Ids
$this->user = is_object($this->user) ? $this->user : (is_numeric($this->userId) ? Job::find($this->userId) : $this->user);
$this->item = is_object($this->item) ? $this->item : (is_numeric($this->itemId) ? Item::find($this->itemId) : $this->item);
// Get my data == measure 'MatrixPowerSliderRange.load.returnPower'
$this->value = $this->user
->returnPower($this->item, $this->aspect, $this->kind);
}
public function render()
{
$return = null;
$this->load(); // tried to load into render, into mount, ...
// ==> measure 'MatrixPowerSliderRange.render'
return view('livewire.matrix-power-slider-range');
}
}
Versions:
- livewire/livewire (v2.4.3)
- Laravel Framework 8.38.0
