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