@@ -8,14 +8,24 @@ Symfony is fast, right out of the box. However, you can make it faster if you
88optimize your servers and your applications as explained in the following
99performance checklists.
1010
11- Symfony Application Checklist
12- -----------------------------
11+ Performance Checklists
12+ ----------------------
1313
14- These are the code and configuration changes that you can make in your Symfony
15- application to improve its performance:
14+ Use these checklists to verify that your application and server are configured
15+ for maximum performance:
1616
17- #. :ref: `Install APCu Polyfill if your server uses APC <performance-install-apcu-polyfill >`
18- #. :ref: `Dump the service container into a single file <performance-service-container-single-file >`
17+ * **Symfony Application Checklist **:
18+
19+ #. :ref: `Install APCu Polyfill if your server uses APC <performance-install-apcu-polyfill >`
20+
21+ * **Production Server Checklist **:
22+
23+ #. :ref: `Dump the service container into a single file <performance-service-container-single-file >`
24+ #. :ref: `Use the OPcache byte code cache <performance-use-opcache >`
25+ #. :ref: `Configure OPcache for maximum performance <performance-configure-opcache >`
26+ #. :ref: `Don't check PHP files timestamps <performance-dont-check-timestamps >`
27+ #. :ref: `Configure the PHP realpath Cache <performance-configure-realpath-cache >`
28+ #. :ref: `Optimize Composer Autoloader <performance-optimize-composer-autoloader >`
1929
2030.. _performance-install-apcu-polyfill :
2131
@@ -72,19 +82,6 @@ container into a single file, which could improve performance when using
7282 // ...
7383 $container->setParameter('container.dumper.inline_factories', true);
7484
75- Production Server Checklist
76- ---------------------------
77-
78- These are the changes that you can make in your production server to improve
79- performance when running Symfony applications:
80-
81- #. :ref: `Use the OPcache byte code cache <performance-use-opcache >`
82- #. :ref: `Use the OPcache class preloading <performance-use-preloading >`
83- #. :ref: `Configure OPcache for maximum performance <performance-configure-opcache >`
84- #. :ref: `Don't check PHP files timestamps <performance-dont-check-timestamps >`
85- #. :ref: `Configure the PHP realpath Cache <performance-configure-realpath-cache >`
86- #. :ref: `Optimize Composer Autoloader <performance-optimize-composer-autoloader >`
87-
8885 .. _performance-use-opcache :
8986
9087Use the OPcache Byte Code Cache
@@ -212,6 +209,120 @@ deployment process too):
212209 used in your application and prevents Composer from scanning the file system for
213210 classes that are not found in the class map. (see: `Composer's autoloader optimization `_).
214211
212+ .. _profiling-applications :
213+
214+ Profiling Applications
215+ ----------------------
216+
217+ `Blackfire `_ is the best tool to profile and optimize performance of Symfony
218+ applications during development, test and production. It's a commercial service,
219+ but provides free features that you can use to find bottlenecks in your projects.
220+
221+ Symfony provides a basic performance profiler in the development
222+ :ref: `config environment <configuration-environments >`. Click on the "time panel"
223+ of the :ref: `web debug toolbar <web-debug-toolbar >` to see how much time Symfony
224+ spent on tasks such as making database queries and rendering templates.
225+
226+ Custom Profiling
227+ ~~~~~~~~~~~~~~~~
228+
229+ You can measure the execution time and memory consumption of your own code and
230+ display the result in the Symfony profiler thanks to the `Stopwatch component `_.
231+
232+ When using :ref: `autowiring <services-autowire >`, type-hint any controller or
233+ service argument with the :class: `Symfony\\ Component\\ Stopwatch\\ Stopwatch ` class
234+ and Symfony will inject the ``debug.stopwatch `` service::
235+
236+ use Symfony\Component\Stopwatch\Stopwatch;
237+
238+ class DataExporter
239+ {
240+ private $stopwatch;
241+
242+ public function __construct(Stopwatch $stopwatch)
243+ {
244+ $this->stopwatch = $stopwatch;
245+ }
246+
247+ public function export()
248+ {
249+ // the argument is the name of the "profiling event"
250+ $this->stopwatch->start('export-data');
251+
252+ // ...do things to export data...
253+
254+ // reset the stopwatch to delete all the data measured so far
255+ // $this->stopwatch->reset();
256+
257+ $this->stopwatch->stop('export-data');
258+ }
259+ }
260+
261+ If the request calls this service during its execution, you'll see a new
262+ event called ``export-data `` in the Symfony profiler.
263+
264+ The ``start() ``, ``stop() `` and ``getEvent() `` methods return a
265+ :class: `Symfony\\ Component\\ Stopwatch\\ StopwatchEvent ` object that provides
266+ information about the current event, even while it's still running. This
267+ object can be converted to a string for a quick summary::
268+
269+ // ...
270+ dump((string) $this->stopwatch->getEvent()); // dumps e.g. '4.50 MiB - 26 ms'
271+
272+ You can also profile your template code with the :ref: `stopwatch Twig tag <reference-twig-tag-stopwatch >`:
273+
274+ .. code-block :: twig
275+
276+ {% stopwatch 'render-blog-posts' %}
277+ {% for post in blog_posts%}
278+ {# ... #}
279+ {% endfor %}
280+ {% endstopwatch %}
281+
282+ Profiling Categories
283+ ....................
284+
285+ Use the second optional argument of the ``start() `` method to define the
286+ category or tag of the event. This helps keep events organized by type::
287+
288+ $this->stopwatch->start('export-data', 'export');
289+
290+ Profiling Periods
291+ .................
292+
293+ A `real-world stopwatch `_ not only includes the start/stop button but also a
294+ "lap button" to measure each partial lap. This is exactly what the ``lap() ``
295+ method does, which stops an event and then restarts it immediately::
296+
297+ $this->stopwatch->start('process-data-records', 'export');
298+
299+ foreach ($records as $record) {
300+ // ... some code goes here
301+ $this->stopwatch->lap('process-data-records');
302+ }
303+
304+ $event = $this->stopwatch->stop('process-data-records');
305+ // $event->getDuration(), $event->getMemory(), etc.
306+
307+ // Lap information is stored as "periods" within the event:
308+ // $event->getPeriods();
309+
310+ Profiling Sections
311+ ..................
312+
313+ Sections are a way to split the profile timeline into groups. Example::
314+
315+ $this->stopwatch->openSection();
316+ $this->stopwatch->start('validating-file', 'validation');
317+ $this->stopwatch->stopSection('parsing');
318+
319+ $events = $this->stopwatch->getSectionEvents('parsing');
320+
321+ // later you can reopen a section passing its name to the openSection() method
322+ $this->stopwatch->openSection('parsing');
323+ $this->stopwatch->start('processing-file');
324+ $this->stopwatch->stopSection('parsing');
325+
215326Learn more
216327----------
217328
@@ -225,3 +336,6 @@ Learn more
225336.. _`APCu PHP functions` : https://www.php.net/manual/en/ref.apcu.php
226337.. _`cachetool` : https://github.com/gordalina/cachetool
227338.. _`open_basedir` : https://www.php.net/manual/ini.core.php#ini.open-basedir
339+ .. _`Blackfire` : https://blackfire.io/docs/introduction?utm_source=symfony&utm_medium=symfonycom_docs&utm_campaign=performance
340+ .. _`Stopwatch component` : https://symfony.com/components/Stopwatch
341+ .. _`real-world stopwatch` : https://en.wikipedia.org/wiki/Stopwatch
0 commit comments