31

My ZF2 application seems to be extremely slow when more than 3 users are using it at the same time.

I profile my code with xdebug and webgrind and non of my functions seems to be slow so it has to be an optimalisation issue within the zf2 it's self.

For cache I make use of the EdpSuperluminal module by EvanDotPro, this seems to increase the performance of the application.

We make use of nginx reverse proxy but make no sense as well.

I need some good advices to increase the response for high traffic. I speak about 30+ connected user at the same time.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
directory
  • 3,093
  • 8
  • 45
  • 85

5 Answers5

43

There's few very simple steps to achieve a faster application. There's three things that can always be considered.

  1. ZF2 Performance QuickTipp #1 - ViewModels Always manually assign the fully qualified script to render. This will increase the performance a little. It's done like this:

    public function someAction()
    {
        $viewModel = new ViewModel();
        $viewModel->setTemplate('MODULE / CONTROLLER / ACTION.phtml');
        // In this given example: $viewModel->setTemplate('foo/bar/some.phtml');
    
        // Do some other Controller-logic as used to
    
        return $viewModel->setVariables(array(
            //key-value-paired view-variables
        ));
    }
    
  2. ZF2 Performance QuickTipp #2 - Classmap Autoloading This probably is one of the most important parts of speeding up your application. Personally i've seen an increase in LoadingTimes by up to 40%. Implementing this is pretty simple:

    class Module 
    {
        public function getAutoloaderConfig()
        {
            return array(
               'Zend\Loader\ClassMapAutoloader' => array(
                    __DIR__ . '/autoload_classmap.php',
               ),
            );
        }
    }
    

    The autoload_classmap.php then is a simple array of 'FQ-CLASSNAME' => 'FQ-FILEPATH'. This can be automatted pretty easily using the classmap_generator-utility of ZF2

  3. ZF2 Performance QuickTipp #3 - Keep Module.php light! Sadly this is a post i haven't come around to write yet. The Module.php is a file that is loaded on every single request. Lots of people forget about this and write lots and lots of factories inside them. At one point, ZfcUser-Module.php was an example of what not to do. Closures or anonymous functions are executed on every request, too. This is quite a bit of work to be done if there's too many of them over the whole project. A better approach would be to simply write Factory-Classes. ZfcUser later updated Module.php to use this strategy.

And that's pretty much all the easy stuff one can do (that i know of - i dont know much! :D). However what sounds interesting is that starting to use 3 users your application runs slow. To my experience this has nothing to do with the scripts itself but is rather an server issue. Is this from a Staging Machine or locally?

claytond
  • 1,061
  • 9
  • 22
Sam
  • 16,435
  • 6
  • 55
  • 89
  • Thanks for your comment Sam. I use all these solutions already :) I work with php server side file caching aswel. It's not that the application is slow with 3 visitors but it's the 'starting' point of losing performance. with 30 active visitors, response time can be up to 8s for a page to be loaded. We can exclude a server issue. We did a lot on performance. Before this same application was running on some raw (dirty) php and that was fast, even with 30+ active visitors. – directory Feb 03 '13 at 12:37
  • 8s, wow. This really is something within your direct scripts. Because running the Skeleton with 50 Active Users gives me no problems. So it will be end user stuff inside your scripts, but to debug this, we would know whats wrong there :S On my end, it has been the DB Connection at one point :) – Sam Feb 03 '13 at 19:38
  • 1
    What did you use to debug your code? I profiled my code and analyzed the cache output with webgrind. I couldn't find any slow function of my own :/ ... At the moment, 15s for a page load, server load 25.00. CPU 100% (2 GHz) not good at all . ;( – directory Feb 03 '13 at 22:13
  • Xdebug and WinCacheGrind, so essentially the same u did. I noticed, boiling down the Zend Code, that the bottleneck was inside the DB\Adapter classes `__construct` - so the db connection. A pageload of that length sure has a big jump in load time between some of ur functions. So the grind HAS to reveal something, but im not an experienced debugger myself, sorry – Sam Feb 04 '13 at 06:42
  • Today I upgraded our web server with 2GHz (extra core) and this seems to do give the application a boost. Php parse time, around 100ms with good traffic. Conclusion; Zend Framework is asking for some more performance of your web server (quite logic because it's still a framework). – directory Feb 05 '13 at 19:00
29

If you are using Doctrine, don't forget to add a cache for annotations. This drastically improve performance (when I activate this cache I divide nearly by two the loading time). If you are using DoctrineORMModule:

'doctrine' => array(
    'driver' => array(

        'cache' => array(
            'class' => 'Doctrine\Common\Cache\ApcCache'
        ),

        'configuration' => array(
            'orm_default' => array(
                'metadata_cache' => 'apc',
                'query_cache'    => 'apc',
                'result_cache'   => 'apc'
            )
        ),
    )
)

However, it's quite inconvenient while developing because you must clear the cache whenever your mapping change.

Michael Gallego
  • 1,746
  • 1
  • 20
  • 29
  • I don't know who down voted this. This is a great answer. Doctrine; if you're not using it, you should but it does cause slowdown without cache. – Bluebaron Jun 18 '13 at 15:08
  • 1
    +1, deploy the cache! I have appropriate config/autoload/local..php.dist files which I can swap out depending on the environment, each of which overrides the defaults in config/autoload/global.php which resolves the development issue. – El Yobo Dec 18 '13 at 01:40
  • 1
    I tried to use the configuration and it did nor work. After spending a couple of hour, I fixed that issue and I found that this answer is outdated. @michael-gallengo Can you please update it? – Ujjwal Ojha Nov 07 '14 at 06:38
27

the ZF2 classmap generator will give you a big boost if you have a large project:

http://framework.zend.com/manual/2.0/en/modules/zend.loader.classmap-generator.html

Alternatively if you are using composer (you should do) then you can use composer to generate the classmap for all your modules and dependdencies too which is even better:

php composer.phar install --optimize-autoloader

php composer.phar update --optimize-autoloader
Andrew
  • 12,617
  • 1
  • 34
  • 48
  • Agreed; composer is generally going to be a better approach, as you're probably using it anyway (best way to install ZF2 components anyway) and you'll want it to autoload all of your composer libs... so you might as well only have one autoloader. – El Yobo Dec 18 '13 at 01:38
3

All of the above and using some kind of opcode caching like APC / Opcache it will speed things up. But yes ZF 2 seems to be very slow unfortunately even more slow then ZF 1 :(

Also the module config cache speeds things up, you cannot have any closures though to make this working ;)

http://hounddog.github.io/blog/performance-in-zend-framework-2/

Chris
  • 8,168
  • 8
  • 36
  • 51
2

First of all to speedup your zf2 application you should use ZendOptimizerPlus. The vast part of execution time used to read and precompile php code. Typical ZF2 app has a lot of files, so it takes a lot of time to handle them.

ZendOp+ saves bytecode of your php application in shared memory, so server doesn't read a lot of files and doesn't parse it every request. ZendOp+ will be at php5.5 by default, so it is useful to know it and to use it.

Benchmarks gives 9x increase in performance for simple framework applications (symfony2 tests - http://www.ricardclau.com/2013/03/apc-vs-zend-optimizer-benchmarks-with-symfony2/ ).

I use it for my zf2 + doctrine2 + zfcUser application. Memcached is used for doctrine2 purposes, it gives only about 5% performance increase. So with ZendOp+ I got 6x increase (0.2 -> 0.03s) for simple pages and 3x increase (0.2 - 0.06) for complex pages with a lot of forms, entities, views. If I use classmap generator, I will update the answer.

Another issue is to use nginx + php-fpm rather than apache2+module. It saves server resources.

shukshin.ivan
  • 11,075
  • 4
  • 53
  • 69