PHP class preloading is one of the most important features added in PHP 7.4. On server startup - before any application code is run - PHP can load a certain set of PHP files into memory and make their contents permanently available to all subsequent requests.
During preloading, PHP also resolves class dependencies and links with parent, interfaces and traits. It also removes unnecessary includes and performs some other optimizations. The overall result is a very significant performance improvement in real applications.
Symfony is compatible with PHP preloading since 4.4 version. In Symfony 5.1
we've improved preloading to make it easier to configure thanks to two new
dependency injection tags called container.preload
and container.no_preload
.
First, container.preload
allows you to define which classes must be
preloaded by PHP. Add one or more of these tags in your services to preload as
many classes as you need. For example, in Symfony code we use this tag to
preload some classes related to the twig
service:
1 2 3 4 5 6 7 8 9 10
services:
twig:
class: Twig\Environment
# ...
tags:
- { name: 'container.preload', class: 'Twig\Cache\FilesystemCache' }
- { name: 'container.preload', class: 'Twig\Extension\CoreExtension' }
- { name: 'container.preload', class: 'Twig\Extension\EscaperExtension' }
- { name: 'container.preload', class: 'Twig\Extension\OptimizerExtension' }
# ...
The container.no_preload
tag is used to tell PHP that it must not preload a
certain class. In this case, the tag doesn't define a class
attribute.
Instead, apply the tag to some service and the class related to that service
won't be preloaded:
1 2 3 4 5 6
services:
twig.template_cache_warmer:
class: Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheWarmer
# ...
tags:
- { name: 'container.no_preload' }
Another change related to PHP preloading is that the warmUp()
method of the
Symfony cache warmers now must return an array with the FQCN (fully-qualified
class names) of the classes to warm up. Not doing that is deprecated since Symfony 5.1.
We've already implemented all these features in Symfony code. The result is that in our synthetic benchmarks, a sample application went from 360 requests per second to 630 requests per second, a 75% performance improvement.
In your own applications, performance improvements will vary. To learn more about preloading in Symfony applications, sign up for the next SymfonyLive Online event which will take place on Friday, April 17.