Symfony2 performance issues and improvements

26
Symfony2 performance issues and improvements Symfony2 performance issues and improvements Vitaliy Berdylo [email protected] https://github.com/vitaliyberdylo

Transcript of Symfony2 performance issues and improvements

Page 1: Symfony2 performance issues and improvements

Symfony2 performance issues and improvements

Symfony2 performance issues and improvements

Vitaliy [email protected]

https://github.com/vitaliyberdylo

Page 2: Symfony2 performance issues and improvements

Symfony2 performance issues and improvements

WHAT is Performance

- Server response time

- Render response time

Page 3: Symfony2 performance issues and improvements

Symfony2 performance issues and improvements

Premature optimization

Page 4: Symfony2 performance issues and improvements

Symfony2 performance issues and improvements

Measure performance

Page 5: Symfony2 performance issues and improvements

Symfony2 performance issues and improvements

Measure serverside performance

Backend benchmarks:

- ab ApacheBanch- siege

Profiler:

- XHProf + XHGui- Blackfire

Enable the slow query log

Page 6: Symfony2 performance issues and improvements

Symfony2 performance issues and improvements

Measure client performance

Client benchmark:

- YSlow- PageSpeed

online:

https://gtmetrix.com/

http://www.webpagetest.org/

Page 7: Symfony2 performance issues and improvements

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

Page 8: Symfony2 performance issues and improvements

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

Page 9: Symfony2 performance issues and improvements

Symfony2 performance issues and improvements

kernel.request event issues

- Avoid calling a database or external services in listeners- Don’t 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; }

// ...}

Page 10: Symfony2 performance issues and improvements

Symfony2 performance issues and improvements

User don’t need wait

Page 11: Symfony2 performance issues and improvements

Symfony2 performance issues and improvements

Do blocking work in the background

Page 12: Symfony2 performance issues and improvements

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 <= 10000; ++$i) { $user = new User; $user->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();

Page 13: Symfony2 performance issues and improvements

Symfony2 performance issues and improvements

Enable doctrine cache

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

Page 14: Symfony2 performance issues and improvements

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 // ...

Page 15: Symfony2 performance issues and improvements

Symfony2 performance issues and improvements

Custom caching service

<?php

namespace Acme\DemoBundle\Doctrine\Cache;

use Doctrine\Common\Cache\CacheProvider

class MyCache extends CacheProvider{ protected function doFetch($id) {}

protected function doContains($id) {} protected function doSave($id, $data, $lifeTime = 0) {} protected function doDelete($id) {} protected function doFlush() {} protected function doGetStats() {}}

Page 16: Symfony2 performance issues and improvements

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();}

Page 17: Symfony2 performance issues and improvements

Symfony2 performance issues and improvements

Beware of lazy loading

Page 18: Symfony2 performance issues and improvements

Symfony2 performance issues and improvements

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

{% for article in articles %} <article> <h2>{{ article.title }}</h2> <p>Author: {{ article.author.firstName }} {{ article.author.lastName }}</p> <p>{{ article.text }}</p> </article>{% endfor %}

Page 19: Symfony2 performance issues and improvements

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> <h2>{{ article.title }}</h2> <p>Author: {{ article.author.firstName }} {{ article.author.lastName }}</p> <p>{{ article.text }}</p> </article>{% endfor %}

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

Page 20: Symfony2 performance issues and improvements

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();}

Page 21: Symfony2 performance issues and improvements

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();

Page 22: Symfony2 performance issues and improvements

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));

Page 23: Symfony2 performance issues and improvements

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

Page 24: Symfony2 performance issues and improvements

Symfony2 performance issues and improvements

Use reverse proxy

Page 25: Symfony2 performance issues and improvements

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

Page 26: Symfony2 performance issues and improvements

Symfony2 performance issues and improvements

Questions & Answers