Description
The ContainerAwareEventDispatcher
only loads services registered as listeners for events which are actually fired in an app. However, the instantiation of all listeners for a given event happens prior to dispatching and therefore this optimization does not help too much for events which potentially stop propagation (e.g. KernelEvent::REQUEST
). Especially when there are lots of listeners with many dependencies (e.g. Drupal), instantiating services can be quite expensive.
As a result of the preliminary service construction, the time until the first listener is fired depends on the amount of listeners registered for that event. A little experiment showed that delaying instantiation until the respective listener is triggered might result in much quicker response times for early listeners. I've conducted this experiment on a standard unchanged, non-optimized Drupal 8 installation with a sloppily hacked version of the ContainerAwareEventDispatcher
:
- Standard
ContainerAwareEventDispatcher
:
Time to first request-listener: ~130ms, number of instantiated services: 132 of 369 - Modified
ContainerAwareEventDispatcher
:
Time to first request-listener: ~70ms, number of instantiated services: 36 of 369
The main roadblock for a proper implementation are the public getListeners()
and the protected doDispatch()
methods because they operate on lists of callables.
Any ideas on how such an optimization could be realized without changing the existing API?