Improve FluxServiceProvider boot performance#2437
Open
joshhanley wants to merge 5 commits intomainfrom
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Scenario
FluxServiceProvideradds measurable overhead to every request's boot phase. One user reported 215ms, while our own benchmarking shows 6-11ms in the browser and a median of 5.5ms across 100 CLI cold-starts:The Problem
FluxServiceProvideris the first service provider to resolveblade.compilerduring the boot phase. This triggers autoloading of Laravel's entire view layer (BladeCompiler,Compiler,Factory,FileViewFinder,EngineResolver, and theBladefacade) before any other provider has needed them.On top of that,
app('flux')->boot()forces autoloading ofLivewire\Componentjust to register amodalmacro, and theFluxTagCompileris eagerly instantiated even though it's only needed when Blade actually compiles a view.Most of the boot time (~10 of the 15 classes loaded) consists of core Laravel and Livewire classes that would be loaded anyway by Livewire's own service provider moments later. Flux just happens to trigger them first due to boot order.
The Solution
Three changes to defer work until it's actually needed:
callAfterResolving('blade.compiler', ...)- Instead of eagerly resolving the blade compiler (and triggering view layer autoloading), register a callback that fires when the compiler is first resolved by whoever actually needs it (typically Livewire). Component paths, directives, and the precompiler are all registered inside this callback.$this->app->booted(...)- DeferbootMacros(),propertySynthesizer, andapp('flux')->boot()until after all service providers have booted. These are only needed at render time, not during the boot phase.Lazy
FluxTagCompiler- The compiler is created on first Blade precompilation rather than eagerly during boot.After the change:
The total request time stays the same (the same classes are still loaded), but the cost is correctly attributed to the service that actually needs them rather than to Flux.
Fixes #1846