Symfony2 is said to be slow. Nothing can be further from the truth! Our Symfony2 instances handle more than 600 req/s and are working great. To have such results, everything needs some performance optimizations.
Following a great feedback after our previous post about Doctrine’s performance (thank you! :-)), we decided to give you some more advices of reaching the top from your Symfony2 projects.
We’re going to make separate article which will show you what to not afraid of in Symfony2 ecosystem (annotations, Twig etc.) so stay tuned! 🙂
1. Use Stopwatch Component to profile your code
Thanks to the Stopwatch Component, you’re able to see times needed to run parts of your code and amount of memory consumed by it.
The common use case is to track the time needed to perform connections to the third party webservices.
The resulting graph of a code-flow will be showed in your Symfony2 developer’s toolbar.
Sample usage of Stopwatch Component to profile connection to Twitter API
Note that in Production environment (with debug=false
) Stopwatch isn’t initialized so we have to use on-invalid="null"
in service configuration
2. Beware of forms
Symfony Form Component is one of the most complex feature of the whole Symfony stack. It can handle almost every use case you’ll likely need. Including collections of fields, sub-forms which depend on the values from the other fields, conditional validations based on the form values and much more.
The Form Component evolved since last years. Symfony Contributors have made great work to enhance it even further. We’re observing another features implemented to it and also the work done for optimizing performance of such complex component.
The performance problems with Symfony forms were visible in the first versions of 2.* branch. Nowadays it isn’t mostly anything crucial. Of course, you must be aware that they will add extra milliseconds of loading time but that is a cost of every next complex component (think ORM).
We think, that the benefits of the possibility of faster development, are worth some performance loss.
But still, to give you some advice — don’t create multiple forms in one page – creating forms in a foreach loop is as bad idea as running SQL queries in it.
3. Use HTTP Cache and fragment caching
Caching is the thing that obviously led to the most performance gains. As closer the Caching will be to the end-user, as faster the site will load.
Using Varnish and ESI (for fragments caching) will do the most work for optimizing your application. To not reinvent the wheel, we just suggest you to read the dedicated section from the Symfony Book – HTTP Cache.
4. Always use Composer’s class-loading optimization
Use php composer.phar install -o
for the best class loader performance.
Internally, default class loader uses file_exists
function to check for the existence of the class in specified file based on its name and namespace.
Using --optimize
(-o) option, Composer is building a big association array with FQDNClassName => Path/To/ClassName.php
mapping. That results in a lower number of calls for file_exists
for vendor classes.
Drupal team insights on optimized ClassLoader
5. Enable a Byte Code Cache and ApcClassLoader in app.php
Enabling APC is the first thing you should do to optimize the speed of your PHP application. APC caches PHP to the byte code so that it isn’t necessary to always recompile PHP files.
To even enhance the Symfony, you should enable the ApcClassLoader (located in web/app.php). Internally, it uses APC to store the paths of the classes.
6. Add common classes to compile on cache warmup
On the first run, Symfony2 is building a big cache of commonly used classes. The resulting file can be found in app/cache/{env}/classes.php
. It can optimize the IO in the class loading process reducing the number of files needed to be open.
Using Symfony\Component\HttpKernel\DependencyInjection\Extension
class in your own bundle, you can add your classes to that cache.
It’s as easy as adding:
$this->addClassesToCompile(array(
'FQDN\\ClassName',
));
to your Acme\MainBundle\DependencyInjection\AcmeMainExtension
class.
Remember that it won’t work for classes for which you declare configuration as annotations (eg. ORM’s @Entity or Validation).
Extension::addClassesToCompile
Photo by Titus Hageman
Are you looking for an experienced Symfony2 developers?
Check out our offer!