大家都知道 laravel 项目写起来是挺爽,但是在生产环境性能不高,我们来抽丝剥茧分析我自己项目的运行时间消耗:

Bootstrap 耗时

步骤 耗时
Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables 0.3058910369873
Illuminate\Foundation\Bootstrap\LoadConfiguration 3.6571025848389
Illuminate\Foundation\Bootstrap\HandleExceptions 0.78296661376953
Illuminate\Foundation\Bootstrap\RegisterFacades 9.0579986572266
Illuminate\Foundation\Bootstrap\RegisterProviders 101.02701187134
Illuminate\Foundation\Bootstrap\BootProviders 96.982002258301

观察初步结论: laravel 在调用 Illuminate\Foundation\Bootstrap\RegisterProvidersIlluminate\Foundation\Bootstrap\BootProvidersbootstrap 方法时,消耗时间是大头。

  • Illuminate\Foundation\Bootstrap\RegisterProviders 是用于注册服务提供者的。
  • Illuminate\Foundation\Bootstrap\BootProviders 是用于启动服务提供者的。
  • laravel 的内置server php artisan serve 自带了优化机制,上面数据仅体现首次加载的耗时。二次加载时会相比少很多。但此优化在 fpm 下无效。

我们进一步分析。


RegisterProviders 耗时

\Illuminate\Foundation\Bootstrap\RegisterProviders::bootstrap 方法代码如下:

    /**
* Bootstrap the given application.
*
* @param \Illuminate\Foundation\Application $app
* @return void
*/
public function bootstrap(Application $app)
{
$app->registerConfiguredProviders();
}

所以我们还是回到了 \Illuminate\Foundation\Application 这个文件:


/**
* Register all of the configured providers.
*
* @return void
*/
public function registerConfiguredProviders()
{
$providers = Collection::make($this->config['app.providers'])
->partition(function ($provider) {
return Str::startsWith($provider, 'Illuminate\\');
}); $providers->splice(1, 0, [$this->make(PackageManifest::class)->providers()]); (new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath()))
->load($providers->collapse()->toArray());
}

针对上面的 (new ProviderRepository)->load 进行耗时分析发现数据为

步骤 耗时
Illuminate\Foundation\ProviderRepository::load 61.771869659424

毋庸置疑这就是消耗时间的大头。

里面的代码为


/**
* Register the application service providers.
*
* @param array $providers
* @return void
*/
public function load(array $providers)
{
$manifest = $this->loadManifest(); // First we will load the service manifest, which contains information on all
// service providers registered with the application and which services it
// provides. This is used to know which services are "deferred" loaders.
if ($this->shouldRecompile($manifest, $providers)) {
$manifest = $this->compileManifest($providers);
} // Next, we will register events to load the providers for each of the events
// that it has requested. This allows the service provider to defer itself
// while still getting automatically loaded when a certain event occurs.
foreach ($manifest['when'] as $provider => $events) {
$this->registerLoadEvents($provider, $events);
} // We will go ahead and register all of the eagerly loaded providers with the
// application so their services can be registered with the application as
// a provided service. Then we will set the deferred service list on it.
foreach ($manifest['eager'] as $provider) {
$this->app->register($provider);
} $this->app->addDeferredServices($manifest['deferred']);
}

而再经过定位,发现慢在这一行

        foreach ($manifest['eager'] as $provider) {
$this->app->register($provider);
}

又回到 \Illuminate\Foundation\Application

    /**
* Register a service provider with the application.
*
* @param \Illuminate\Support\ServiceProvider|string $provider
* @param array $options
* @param bool $force
* @return \Illuminate\Support\ServiceProvider
*/
public function register($provider, $options = [], $force = false)
{
if (($registered = $this->getProvider($provider)) && ! $force) {
return $registered;
} // If the given "provider" is a string, we will resolve it, passing in the
// application instance automatically for the developer. This is simply
// a more convenient way of specifying your service provider classes.
if (is_string($provider)) {
$provider = $this->resolveProvider($provider);
} if (method_exists($provider, 'register')) {
$provider->register();
} // If there are bindings / singletons set as properties on the provider we
// will spin through them and register them with the application, which
// serves as a convenience layer while registering a lot of bindings.
if (property_exists($provider, 'bindings')) {
foreach ($provider->bindings as $key => $value) {
$this->bind($key, $value);
}
} if (property_exists($provider, 'singletons')) {
foreach ($provider->singletons as $key => $value) {
$this->singleton($key, $value);
}
} $this->markAsRegistered($provider); // If the application has already booted, we will call this boot method on
// the provider class so it has an opportunity to do its boot logic and
// will be ready for any usage by this developer's application logic.
if ($this->booted) {
$this->bootProvider($provider);
} return $provider;
}

在 register 方法中,根据 get_class($provider) 和 执行耗时,得出以下数据

步骤 耗时
Illuminate\Events\EventServiceProvider 0.02197265625
Illuminate\Log\LogServiceProvider 0.005859375
Illuminate\Routing\RoutingServiceProvider 0.011962890625
Illuminate\Auth\AuthServiceProvider 0.024169921875
Illuminate\Cookie\CookieServiceProvider 0.0048828125
Illuminate\Database\DatabaseServiceProvider 9.678955078125
Illuminate\Encryption\EncryptionServiceProvider 0.00732421875
Illuminate\Filesystem\FilesystemServiceProvider 0.014892578125
Illuminate\Foundation\Providers\FormRequestServiceProvider 0.0009765625
Illuminate\Foundation\Providers\FoundationServiceProvider 0.416015625
Illuminate\Notifications\NotificationServiceProvider 0.011962890625
Illuminate\Pagination\PaginationServiceProvider 5.04296875
Illuminate\Session\SessionServiceProvider 0.072021484375
Illuminate\View\ViewServiceProvider 0.01318359375
Cog\Laravel\Love\Providers\LoveServiceProvider 0.01708984375
Dingo\Api\Provider\RoutingServiceProvider 0.0146484375
Dingo\Api\Provider\HttpServiceProvider 0.03271484375
Dingo\Api\Provider\LaravelServiceProvider 20.23583984375
Fideloper\Proxy\TrustedProxyServiceProvider 0.001953125
InfyOm\AdminLTETemplates\AdminLTETemplatesServiceProvider 0.001953125
InfyOm\Generator\InfyOmGeneratorServiceProvider 0.045166015625
JeroenNoten\LaravelAdminLte\ServiceProvider 0.013671875
Laracasts\Flash\FlashServiceProvider 0.013916015625
Laravelfy\Validator\ServiceProvider 0.001953125
Lshorz\Luocaptcha\LCaptchaServiceProvider 0.01171875
Maatwebsite\Excel\ExcelServiceProvider 6.778076171875
Overtrue\LaravelWeChat\ServiceProvider 9.040771484375
Prettus\Repository\Providers\EventServiceProvider 0.00390625
Prettus\Repository\Providers\RepositoryServiceProvider 1.244140625
Spatie\Permission\PermissionServiceProvider 0.3759765625
Tymon\JWTAuth\Providers\LaravelServiceProvider 0.03515625
Collective\Html\HtmlServiceProvider 0.025146484375
Yajra\DataTables\HtmlServiceProvider 2.22314453125
Yajra\DataTables\ButtonsServiceProvider 4.593017578125
Yajra\DataTables\DataTablesServiceProvider 0.333984375
App\Providers\AppServiceProvider 0.001953125
App\Providers\AuthServiceProvider 0.001953125
App\Providers\EventServiceProvider 0.001953125
App\Providers\RouteServiceProvider 0.001708984375
App\Providers\ResponseMacroServicePrivoder 37.69677734375
Overtrue\LaravelLang\TranslationServiceProvider 0.01220703125
Illuminate\Validation\ValidationServiceProvider 0.029052734375
Illuminate\Cache\CacheServiceProvider 0.01318359375
Illuminate\Hashing\HashServiceProvider 0.031005859375

得出 RegisterProviders 瓶颈的结论

  • App\Providers\ResponseMacroServicePrivoder 占用 37ms
  • Dingo\Api\Provider\LaravelServiceProvider 占用 20ms
  • Illuminate\Database\DatabaseServiceProvider 占用 9ms
  • Overtrue\LaravelWeChat\ServiceProvider 占用 9ms

BootProviders 耗时

服务提供者 启动时间 请求时
Illuminate\Database\DatabaseServiceProvider::boot 0.851074875 3.6809083125
Illuminate\Foundation\Providers\FormRequestServiceProvider::boot 0.022949875 0.0290524375
Illuminate\Notifications\NotificationServiceProvider::boot 2.113769125 9.91894525
Illuminate\Pagination\PaginationServiceProvider::boot 0.062988125 0.089843
EasyWeChatComposer\Laravel\ServiceProvider::boot 6.5910643125 22.644042875
Cog\Laravel\Love\Providers\LoveServiceProvider::boot 0.6311035625 2.3010250625
Dingo\Api\Provider\LaravelServiceProvider::boot 9.228027375 53.9980465
Fideloper\Proxy\TrustedProxyServiceProvider::boot 0.1589356875 0.6091309375
InfyOm\AdminLTETemplates\AdminLTETemplatesServiceProvider::boot 0.033691625 0.0410155
Prettus\Repository\Providers\EventServiceProvider::boot 0.020996375 0.0432120625
Prettus\Repository\Providers\RepositoryServiceProvider::boot 1.7600095625 8.361816625
Laracasts\Flash\FlashServiceProvider::boot 0.191894125 0.066894125
InfyOm\Generator\InfyOmGeneratorServiceProvider::boot 0.0832513125 0.019042875
JeroenNoten\LaravelAdminLte\ServiceProvider::boot 3.2441405 17.807128625
Laravelfy\Validator\ServiceProvider::boot 2.940917875 10.8391118125
Lshorz\Luocaptcha\LCaptchaServiceProvider::boot 0.0832513125 0.075683375
Overtrue\LaravelWeChat\ServiceProvider::boot 0.074707125 0.0139165625
Spatie\Permission\PermissionServiceProvider::boot 9.5026856875 15.3239749375
Tymon\JWTAuth\Providers\LaravelServiceProvider::boot 1.070800125 11.508300125
Yajra\DataTables\DataTablesServiceProvider::boot 0.2839356875 1.0837404375
Yajra\DataTables\HtmlServiceProvider::boot 0.0827631875 0.0651856875
Maatwebsite\Excel\ExcelServiceProvider::boot 0.0461428125 0.0097655
Yajra\DataTables\ButtonsServiceProvider::boot 0.0529785625 0.046875
App\Providers\AppServiceProvider::boot 0.1179191875 0.0979000625
App\Providers\AuthServiceProvider::boot 0.1901856875 0.437988125
App\Providers\EventServiceProvider::boot 0.196777375 0.8210441875
App\Providers\RouteServiceProvider::boot 4.6032714375 12.817871375
App\Providers\ResponseMacroServicePrivoder::boot 5.6691893125 16.917968
Laravel\Tinker\TinkerServiceProvider::boot 0.3859868125 null
Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::boot 0.1750488125 null

原因分析

  • EasyWeChatComposer\Laravel\ServiceProvider::boot 的启动速度,略慢,分析原因: 代码 Github boot 方法中,加载了路由。而 Laravel 的路由,确实是比较慢的。

[未完]

原文地址:https://segmentfault.com/a/1190000016411386

最新文章

  1. Day24_多线程第一天
  2. OAF_文件系列10_实现OAF将数据资料导出Excel到本地JXL(案例)
  3. JavaScript学习笔记-函数
  4. SmartWiki文档在线管理系统简介
  5. [NOI 2014]做题记录
  6. repeater控件实现分页
  7. 最全C语言笔记回顾
  8. TCP的状态
  9. axis1.4开发webservice客户端(快速入门)-基于jdk1.4
  10. Apache Kafka - 介绍
  11. xampp启动MySQL出现Error: MySQL shutdown unexpectedly.
  12. weblogic92一次成功修改密码的记录
  13. IdentityServer3零星笔记
  14. 【Directshow】IFilterGraph::AddFilter方法参数问题<转>
  15. Android 手机 黑域
  16. Siki_Unity_3-8_Lua编程(未完)
  17. Nginx启动/重启失败
  18. setTimeOut和闭包
  19. JS高级程序设计第三版——JavaScript简介
  20. export,source

热门文章

  1. HDU 4510
  2. pl/sql developer 快捷操作: 显示不可见字符 显示历史sql语句 拷贝整个sql窗口的语句至新的sql窗口
  3. Oracle-11-主键约束
  4. Android Handler消息机制深入浅出
  5. 2015年趋势科技笔试A卷
  6. HTTP缓存和CDN缓存
  7. vim下很好的右键复制方法
  8. 【POI 2007】 山峰和山谷
  9. Spring配置之OpenSessionInViewFilter
  10. 11g Rac PSU20180116手动补丁升级步骤