Laravel livewire,呈现性能问题。如何管理数百个组件?

标签 laravel performance render laravel-livewire

当我多次使用同一个组件时,我遇到了 Livewire 的性能问题。 我过去已经遇到过这个问题,每次我都通过关闭框架并直接使用 Vuejs/api 来解决这个问题。 也许我没有正确使用 Livewire ... 或者我错过了某处。

问题:如何管理许多具有参数和模型数据的相同组件的 Livewire 使用,而不增加渲染时间和性能? 我错过了什么 ?有什么建议吗?

提前致谢。

问题:

我有一个包含数百个条目的网页。对于它们中的每一个,我都调用了一个 Livewire 组件。 对于 105 个组件,页面加载需要 8-11 秒。

我使用了 debugbar,发现与应用时间 (8.46) 相比,render livewire 功能非常耗时 (8.29s)。 我审计了一下里面的函数,只有205.53ms。好的,如果我们采取获取数据的部分,则需要 400 毫秒。

debugbar performance

我在阅读之后得出的结论是,根本原因是模型的延迟加载。 事实上,我在我的组件上使用了两个模型(用户和项目):

  <livewire:matrix-power-slider-resume-group :type="$type" :user="$user" :item="$item" aspect="T"></livewire:matrix-power-slider-resume-group>

用户和项目当然有一些关系,但是当我调试它们时,这些关系没有被加载/使用(意味着我应该有一个小的序列化的“json”对象)。所以我不怀疑 big-lazy-model-loading 问题。

我试图传递 ID 而不是模型,并要求我的组件再次获取数据。但是在这里,我激增了查询的数量(120 个参数模型与 +1800 个 ID),由于查询数量,我仍然有非常糟糕的性能(7-11s)。

我在 html 代码之前使用了调试措施,这是一直消耗的部分。不是组件的 render() 函数,不是 mount(),而是 blade 文件中的 livewire render :(

我也试过在类中使用模型声明:

  public function mount($type, $userId, $itemId, $aspect = null, User $user = null, item $item = null)

或不:

  public function mount($type, $userId, $itemId, $aspect = null, $user = null, $item = null)

代码:

<?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');
    }
}

版本:

  • livewire/livewire (v2.4.3)
  • Laravel 框架 8.38.0

最佳答案

首先,您不需要创建一个完整的组件来封装您的逻辑并在每次需要渲染时实例化它。

例如,您可以在主组件中实现逻辑,并在传递编译数据的地方使用布局组件进行渲染。在主要组件中,您可以创建一个名为 loadRow 的函数并将加载逻辑放入其中,在 View 中您可以执行如下操作:

<x-matrix-power-slider-range :data="loadRow($row->type, $row->userId, ...)" />

x-matrix-power-slider-range 中,您可以只获取包含信息的数组并使用它。如果您想添加悬停功能之类的东西,那么您可以实现 hoverRow(),您可以在其中传递标识符并执行您的逻辑。

为了进一步改进这一点,您还可以在开始时获取所有数据,并从 loadRow() 中的数组中使用它;此外,数据缓存也有帮助。

关于Laravel livewire,呈现性能问题。如何管理数百个组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67240963/

相关文章:

linux - 将 IPC(指令/周期)连续传递给其他函数或变量

c++ - 如何识别阻碍我的程序在 32 核 CPU 上良好扩展的瓶颈?

c++ - directX 中的网格动画

api - Postman 对 Laravel 中间件异常没有任何响应

php - 使用 Eloquent 时 Laravel 5.1 加入问题

php - 显示这些日期之间的所有数据

javascript - Express JS 将变量传递给 Javascript 文件

javascript - vm.$set 和 Vue.set 有什么区别?

php - 哪种沟通方式更有效

php - 如何将 CMS 页面的内容拉入静态 block ?