Symfony2 performance issues and improvements

download Symfony2 performance issues and improvements

of 26

  • date post

    15-Apr-2017
  • Category

    Technology

  • view

    940
  • download

    7

Embed Size (px)

Transcript of Symfony2 performance issues and improvements

  • Symfony2 performance issues and improvements

    Symfony2 performance issues and improvements

    Vitaliy Berdylovberdylo@orocrm.com

    https://github.com/vitaliyberdylo

    https://github.com/yshyshkinhttps://github.com/yshyshkinhttps://github.com/yshyshkin

  • Symfony2 performance issues and improvements

    WHAT is Performance

    - Server response time

    - Render response time

  • Symfony2 performance issues and improvements

    Premature optimization

  • Symfony2 performance issues and improvements

    Measure performance

  • Symfony2 performance issues and improvements

    Measure serverside performance

    Backend benchmarks:

    - ab ApacheBanch- siege

    Profiler:

    - XHProf + XHGui- Blackfire

    Enable the slow query log

  • Symfony2 performance issues and improvements

    Measure client performance

    Client benchmark:

    - YSlow- PageSpeed

    online:

    https://gtmetrix.com/

    http://www.webpagetest.org/

  • Symfony2 performance issues and improvements

    Symfony book Performance

    - Use a Byte Code Cache (e.g. APC)- Use Composer's Class Map Functionality- Caching the Autoloader with APC- Use Bootstrap Files

  • Symfony2 performance issues and improvements

    Expensive service construction

    - Be careful with listeners for kernel.request, kernel.controller, kernel.view and kernel.response events.

    - Don't perform any work in the service constructor

    - Minimize deep layers of dependencies

    - Minimize injecting services into listeners

    - Use lazy services

  • Symfony2 performance issues and improvements

    kernel.request event issues

    - Avoid calling a database or external services in listeners- Dont forget check request type and skip listener run for sub-requests

    - Avoid excessive usage of Internal Subrequests. Every sub-request will go through the HttpKernel event lifecycle.

    use Symfony\Component\HttpKernel\Event\GetResponseEvent;// ...

    public function onKernelRequest(GetResponseEvent $event){ if (!$event->isMasterRequest()) { // don't do anything if it's not the master request return; }

    // ...}

  • Symfony2 performance issues and improvements

    User dont need wait

  • Symfony2 performance issues and improvements

    Do blocking work in the background

  • Symfony2 performance issues and improvements

    Doctrine best practice- Constrain relationships as much as possible. Avoid bidirectional associations if possible

    - Avoid composite keys

    - Use lifecycle events judiciously

    -Make $em->clear() in batches$batchSize = 20;for ($i = 1; $i setStatus('user'); $user->setUsername('user' . $i); $user->setName('Mr.Smith-' . $i); $em->persist($user); if (($i % $batchSize) === 0) { $em->flush(); $em->clear(); // Detaches all objects from Doctrine! }}$em->flush(); //Persist objects that did not make up an entire batch$em->clear();

  • Symfony2 performance issues and improvements

    Enable doctrine cache

    doctrine: orm: metadata_cache_driver: apc result_cache_driver: apc query_cache_driver: apc

  • Symfony2 performance issues and improvements

    Enable doctrine cache

    You can use your own service:

    doctrine: orm: metadata_cache_driver: apc result_cache_driver: apc query_cache_driver: apc

    doctrine: orm: metadata_cache_driver: type: service id: acme.demo.doctrine.cache.mycache // ...

  • Symfony2 performance issues and improvements

    Custom caching service

  • Symfony2 performance issues and improvements

    Caching in action/*** Get all articles with best rank* @return array*/public function findBestArticles(){ $query = $this->createQueryBuilder('article') ->select('article.title, article.description, article.published') ->where('article:rank = :rank') ->orderBy('article.published') ->setParameter('rank', 5) ->getQuery(); $query->useResultCache( true, 3600, __METHOD__ . serialize($query->getParameters()) ); $query->useQueryCache(true); return $query->getArrayResult();}

  • Symfony2 performance issues and improvements

    Beware of lazy loading

  • Symfony2 performance issues and improvements

    Beware of lazy loading Beware of lazy loading when querying entities with associations

    {% for article in articles %} {{ article.title }} Author: {{ article.author.firstName }} {{ article.author.lastName }} {{ article.text }} {% endfor %}

  • Symfony2 performance issues and improvements

    Beware of lazy loading Beware of lazy loading when querying entities with associations

    Apparent solution:

    {% for article in articles %} {{ article.title }} Author: {{ article.author.firstName }} {{ article.author.lastName }} {{ article.text }} {% endfor %}

    $articles = $this->getDoctrine()->getRepository('AcmeDemoBundle:Article')->findAll();

  • Symfony2 performance issues and improvements

    Beware of lazy loading Right solution:

    // src/Acme/DemoBundle/Entity/Repository/ArticleRepository

    public function findAllWithAuthors(){ $qb = $this->createQueryBuilder('article'); $qb->addSelect('author') ->innerJoin('article.author', 'author');

    return $qb->getQuery()->getResult();}

  • Symfony2 performance issues and improvements

    Don't use hydration without needs

    Doctrine ORM, like most ORMs, is performing a process called Hydration when converting database results into objects.

    With hydration:

    Without hydration

    $articles = $this->createQueryBuilder('article')->getQuery()->getResult();

    $articles = $this->createQueryBuilder('article')->getQuery()->getResult(Query::HYDRATE_ARRAY);

    $articles = $this->createQueryBuilder('article')->getQuery()->getArrayResult();

  • Symfony2 performance issues and improvements

    Use Reference ProxiesWith get author query into DB:

    Without query for getting author:

    $author = $this->getDoctrine()->getManagerForClass('AcmeDemoBundle:Article')->getRepository('AcmeDemoBundle:Article')->find($authorId);

    $article = new Article();$article->setAuthor($author);

    $em = $this->getDoctrine()->getManagerForClass('AcmeDemoBundle:Article');

    $article = new Article();$article->setAuthor($em->getReference('AcmeDemoBundle:Author', $authorId));

  • Symfony2 performance issues and improvements

    Assets

    - Merging and minifying assets with Assetic (YUI compressor)- CSS at top javascript at bottom- use sprites for images- encode small images into base64- run image optimizations on your images

  • Symfony2 performance issues and improvements

    Use reverse proxy

  • Symfony2 performance issues and improvements

    Bibliography http://blog.hma-info.

    de/content/stuff/Full_Stack_Web_Application_Performance_Tuning.pdf

    http://symfony.com/blog/push-it-to-the-limits-symfony2-for-high-performance-needs

    https://tideways.io/profiler/blog/5-ways-to-optimize-symfony-baseline-performance

    http://ocramius.github.io/blog/doctrine-orm-optimization-hydration

    http://labs.octivi.com/mastering-symfony2-performance-internals

    http://www.emanueleminotto.it/im-afraid-symfony-2-performances

    http://alexandre-salome.fr/media/sfpot-english.pdf

    http://blog.hma-info.de/content/stuff/Full_Stack_Web_Application_Performance_Tuning.pdfhttp://blog.hma-info.de/content/stuff/Full_Stack_Web_Application_Performance_Tuning.pdfhttp://blog.hma-info.de/content/stuff/Full_Stack_Web_Application_Performance_Tuning.pdf

  • Symfony2 performance issues and improvements

    Questions & Answers