如果我有多重模型并且我在事务中工作繁重,那么在我的AppServiceProvider中,我为我的模型创建一个观察者,如:
$(this).parent().next(".show-subcom").fadeToggle().delay(1000);
是否会造成一些性能损失?如果我对每个应用程序访问都正确理解Stand-alone Programs它将循环遍历我的所有模型观察者方法并将它们与雄辩事件相匹配,那么如果我有30个模型观察者,它会导致糟糕的性能吗?
是否有一些聪明的方法只在模型使用时声明observe类?因此,即使不需要,每个模型只有在使用它时才会知道它的观察者,而不是在每个app访问中声明观察者?
答案 0 :(得分:1)
有同样的问题,并对此做了一些研究。
如果打开Laravel随附的
config/app.php
文件,您将看到一个providers
数组。这些都是将为您的应用程序加载的所有服务提供程序类。 请注意,其中许多都是“延迟的”提供程序,这意味着它们不会在每次请求时都加载,而仅在实际需要它们提供的服务时才加载。
如果您的提供者仅在服务容器中注册绑定,则可以选择将其注册推迟到实际需要其中一个注册的绑定为止。 延迟加载此类提供程序将提高应用程序的性能,因为并非每次请求都从文件系统中加载它。
答案 1 :(得分:1)
如果您将事件与Laravel一起使用,则事件将在每次请求时注册(但不会触发)。
更确切地说,将注册事件意味着User::observe(UserObserver::class);
中UserObserver
的{{3}}并将它们保存在User
类的调度程序的数组中。只有执行通过update
模型的create
/ User
方法时,才会触发已注册的UserObserver
方法,即从调度程序中调用。
因此,如果您在Observer类中有30个模型,每个模型具有5个方法,则对调度程序的每个请求都将具有150个数组绑定。但是,只有在事件触发时,才会在每个请求期间调用观察者的方法。因此,与加载120kb Logo或执行查询调用所花费的时间相比,我认为150个数组分配不会对请求时间产生影响。
最好的事情当然是自己衡量。结合观察者与不结合观察者来衡量请求的时间。您可以使用loop through all methods。
旁注:使用debugbar不会有任何区别,因为您必须将旁听者调用放入提供程序的boot
方法中。从文档中:
如果您的提供商仅 在服务容器中注册绑定,则可以选择将其注册推迟到实际需要其中一个注册的绑定为止。
答案 2 :(得分:1)
特别是对于模型观察器,性能影响比典型的事件注册更大。额外的开销来自 Laravel 如何处理观察者事件映射。由于正在注册的事件基于现有方法,Laravel 对每个观察者进行 最少 13 次对 method_exists
的调用。
对于几个观察者来说,这没什么大不了的。但是,如果您开始在审计跟踪流程中使用观察者并涉及多个模型,则此成本可能会开始增加。
举个例子,我曾经开发过一个应用程序,它有四个广义观察者,在它们之间观察了大约 300 个模型(其中一些模型由观察者共享)。这变成了超过 600 次 Model::observe
调用,因此有超过 7,800 次调用 method_exists
。
我实际上创建了一个包 (reedware/laravel-events) 来解决这个问题。相反,您可以通过配置文件注册观察者(和其他事件),并且可以缓存这些事件。缓存机制实际上也适用于观察者(这不适用于 Laravel 开箱即用),因此观察者的成本变得极低。
或者,您可以放弃观察者设计模式,并在可引导特征中使用 Model::creating(...)
钩子,或者只是抛出自定义事件并为它们注册侦听器。