Performance

Symfony is fast, right out of the box. However, you can make it faster if you optimize your servers and your applications as explained in the following performance checklists.

symfony は箱から出してすぐに高速です。ただし、次のパフォーマンス チェックリストで説明されているように、サーバーとアプリケーションを最適化すると、高速化できます。

Performance Checklists

Use these checklists to verify that your application and server are configured for maximum performance:

次のチェックリストを使用して、アプリケーションとサーバーが最大のパフォーマンスを発揮するように構成されていることを確認します。

Install APCu Polyfill if your Server Uses APC

If your production server still uses the legacy APC PHP extension instead of OPcache, install the APCu Polyfill component in your application to enable compatibility with APCu PHP functions and unlock support for advanced Symfony features, such as the APCu Cache adapter.

実稼働サーバーが OPcache の代わりに従来の APC PHP 拡張機能を引き続き使用している場合は、アプリケーションに APCu Polyfill コンポーネントをインストールして、APCu PHP 関数との互換性を有効にし、APCu キャッシュ アダプターなどの高度な Symfony 機能のサポートのロックを解除します。

Restrict the Number of Locales Enabled in the Application

Use the framework.enabled_locales option to only generate the translation files actually used in your application.

アプリケーションで実際に使用される翻訳ファイルのみを生成するには、framework.enabled_locales オプションを使用します。

Dump the Service Container into a Single File

Symfony compiles the service container into multiple small files by default. Set this parameter to true to compile the entire container into a single file, which could improve performance when using "class preloading" in PHP 7.4 or newer versions:

symfony はデフォルトでサービスコンテナを複数の小さなファイルにコンパイルします。このパラメーターを true に設定して、コンテナー全体を単一のファイルにコンパイルします。これにより、PHP 7.4 以降のバージョンで「クラスのプリロード」を使用する場合のパフォーマンスが向上する可能性があります。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
# config/services.yaml
parameters:
    # ...
    container.dumper.inline_factories: true

Use the OPcache Byte Code Cache

OPcache stores the compiled PHP files to avoid having to recompile them for every request. There are some byte code caches available, but as of PHP 5.5, PHP comes with OPcache built-in. For older versions, the most widely used byte code cache is APC.

OPcache は、コンパイル済みの PHP ファイルを保存して、リクエストごとに再コンパイルする必要がないようにします。利用可能なバイト コード キャッシュがいくつかありますが、PHP5.5 の時点で、PHP には OPcache が組み込まれています。古いバージョンでは、最も広く使用されているバイト コード キャッシュは APC です。

Use the OPcache class preloading

Starting from PHP 7.4, OPcache can compile and load classes at start-up and make them available to all requests until the server is restarted, improving performance significantly.

PHP 7.4 以降、OPcache は起動時にクラスをコンパイルしてロードし、サーバーが再起動されるまですべてのリクエストで利用できるようにすることで、パフォーマンスを大幅に向上させます。

During container compilation (e.g. when running the cache:clear command), Symfony generates a file with the list of classes to preload in the var/cache/ directory. Rather than use this file directly, use the config/preload.php file that is created when using Symfony Flex in your project:

コンテナーのコンパイル中 (例: cache:clear コマンドの実行時)、Symfony は、var/cache/ ディレクトリにプリロードするクラスのリストを含むファイルを生成します。このファイルを直接使用するのではなく、プロジェクトで Symfony Flex を使用するときに作成される config/preload.php ファイルを使用します。
1
2
3
4
5
; php.ini
opcache.preload=/path/to/project/config/preload.php

; required for opcache.preload:
opcache.preload_user=www-data

If this file is missing, run this command to update the Symfony Flex recipe: composer recipes:update symfony/framework-bundle.

このファイルが見つからない場合は、次のコマンドを実行して Symfony Flex レシピを更新します:composer レシピ:update symfony/framework-bundle.

Use the container.preload and container.no_preload service tags to define which classes should or should not be preloaded by PHP.

container.preload および container.no_preload サービス タグを使用して、PHP によってプリロードする必要があるクラスとプリロードしないクラスを定義します。

Configure OPcache for Maximum Performance

The default OPcache configuration is not suited for Symfony applications, so it's recommended to change these settings as follows:

デフォルトの OPcache 構成は Symfony アプリケーションには適していないため、これらの設定を次のように変更することをお勧めします。
1
2
3
4
5
6
; php.ini
; maximum memory that OPcache can use to store compiled PHP files
opcache.memory_consumption=256

; maximum number of files that can be stored in the cache
opcache.max_accelerated_files=20000

Don't Check PHP Files Timestamps

In production servers, PHP files should never change, unless a new application version is deployed. However, by default OPcache checks if cached files have changed their contents since they were cached. This check introduces some overhead that can be avoided as follows:

運用サーバーでは、新しいアプリケーション バージョンがデプロイされない限り、PHP ファイルは決して変更されません。ただし、デフォルトでは、OPcache は、キャッシュされたファイルがキャッシュされてから内容が変更されたかどうかをチェックします。このチェックにより、次のように回避できるオーバーヘッドが発生します。
1
2
; php.ini
opcache.validate_timestamps=0

After each deployment, you must empty and regenerate the cache of OPcache. Otherwise you won't see the updates made in the application. Given that in PHP, the CLI and the web processes don't share the same OPcache, you cannot clear the web server OPcache by executing some command in your terminal. These are some of the possible solutions:

各デプロイメントの後、OPcache のキャッシュを空にして再生成する必要があります。そうしないと、アプリケーションで行われた更新が表示されません。 PHP では、CLI と Web プロセスが同じ OPcache を共有しないため、ターミナルでコマンドを実行して Web サーバーの OPcache をクリアすることはできません。考えられる解決策の一部を次に示します。
  1. Restart the web server;
    Web サーバーを再起動します。
  2. Call the apc_clear_cache() or opcache_reset() functions via the web server (i.e. by having these in a script that you execute over the web);
    apc_clear_cache() または opcache_reset() 関数を Web サーバー経由で呼び出します (つまり、これらの関数を Web 上で実行するスクリプトに含めることによって)。
  3. Use the cachetool utility to control APC and OPcache from the CLI.
    CLI から APC と OPcache を制御するには、cachetool ユーティリティを使用します。

Configure the PHP realpath Cache

When a relative path is transformed into its real and absolute path, PHP caches the result to improve performance. Applications that open many PHP files, such as Symfony projects, should use at least these values:

相対パスが実際の絶対パスに変換されると、PHP は結果をキャッシュしてパフォーマンスを向上させます。 Symfony プロジェクトなど、多くの PHP ファイルを開くアプリケーションは、少なくとも次の値を使用する必要があります。
1
2
3
4
5
6
; php.ini
; maximum memory allocated to store the results
realpath_cache_size=4096K

; save the results for 10 minutes (600 seconds)
realpath_cache_ttl=600

Note

ノート

PHP disables the realpath cache when the open_basedir config option is enabled.

open_basedir 設定オプションが有効な場合、PHP は realpath キャッシュを無効にします。

Optimize Composer Autoloader

The class loader used while developing the application is optimized to find new and changed classes. In production servers, PHP files should never change, unless a new application version is deployed. That's why you can optimize Composer's autoloader to scan the entire application once and build an optimized "class map", which is a big array of the locations of all the classes and it's stored in vendor/composer/autoload_classmap.php.

アプリケーションの開発中に使用されるクラス ローダーは、新規および変更されたクラスを検出するように最適化されています。運用サーバーでは、新しいアプリケーション バージョンがデプロイされない限り、PHP ファイルは決して変更されません。そのため、Composer のオートローダーを最適化して、アプリケーション全体を一度スキャンし、最適化された「クラス マップ」を構築できます。これは、すべてのクラスの場所の大きな配列であり、vendor/composer/autoload_classmap.php に保存されます。

Execute this command to generate the new class map (and make it part of your deployment process too):

次のコマンドを実行して、新しいクラス マップを生成します (また、展開プロセスの一部にします)。
1
$ composer dump-autoload --no-dev --classmap-authoritative
  • --no-dev excludes the classes that are only needed in the development environment (i.e. require-dev dependencies and autoload-dev rules);
    --no-dev は、開発環境でのみ必要なクラス (つまり、require-dev 依存関係と autoload-dev ルール) を除外します。
  • --classmap-authoritative creates a class map for PSR-0 and PSR-4 compatible classes used in your application and prevents Composer from scanning the file system for classes that are not found in the class map. (see: Composer's autoloader optimization).
    --classmap-authoritative は、アプリケーションで使用される PSR-0 および PSR-4 互換クラスのクラス マップを作成し、Composer がクラス マップで見つからないクラスのファイル システムをスキャンするのを防ぎます。 (参照: Composer のオートローダーの最適化)。

Profiling Symfony Applications

Profiling with Blackfire

Blackfire is the best tool to profile and optimize performance of Symfony applications during development, test and production. It's a commercial service, but provides free features that you can use to find bottlenecks in your projects.

Blackfire は、開発、テスト、および実稼働中に Symfony アプリケーションのパフォーマンスをプロファイリングおよび最適化するための最良のツールです。これは商用サービスですが、プロジェクトのボトルネックを見つけるために使用できる無料の機能を提供します。

Profiling with Symfony Stopwatch

Symfony provides a basic performance profiler in the development config environment. Click on the "time panel" of the web debug toolbar to see how much time Symfony spent on tasks such as making database queries and rendering templates.

Symfony は、developmentconfig 環境で基本的なパフォーマンス プロファイラーを提供します。 Web デバッグ ツールバーの「時間パネル」をクリックして、Symfony がデータベース クエリの作成やテンプレートのレンダリングなどのタスクに費やした時間を確認します。

You can measure the execution time and memory consumption of your own code and display the result in the Symfony profiler thanks to the Stopwatch component.

Stopwatch コンポーネントのおかげで、独自のコードの実行時間とメモリ消費を測定し、結果を Symfony プロファイラーに表示できます。

When using autowiring, type-hint any controller or service argument with the Stopwatch class and Symfony will inject the debug.stopwatch service:

オートワイヤーを使用する場合、Stopwatch クラスでコントローラーまたはサービス引数をタイプヒントすると、Symfony は debug.stopwatch サービスを注入します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
use Symfony\Component\Stopwatch\Stopwatch;

class DataExporter
{
    private $stopwatch;

    public function __construct(Stopwatch $stopwatch)
    {
        $this->stopwatch = $stopwatch;
    }

    public function export()
    {
        // the argument is the name of the "profiling event"
        $this->stopwatch->start('export-data');

        // ...do things to export data...

        // reset the stopwatch to delete all the data measured so far
        // $this->stopwatch->reset();

        $this->stopwatch->stop('export-data');
    }
}

If the request calls this service during its execution, you'll see a new event called export-data in the Symfony profiler.

リクエストが実行中にこのサービスを呼び出すと、Symfony プロファイラーに export-data という新しいイベントが表示されます。

The start(), stop() and getEvent() methods return a StopwatchEvent object that provides information about the current event, even while it's still running. This object can be converted to a string for a quick summary:

start()、stop()、および getEvent() メソッドは、実行中であっても現在のイベントに関する情報を提供する StopwatchEvent オブジェクトを返します。このオブジェクトは、簡単な要約のために文字列に変換できます。
1
2
// ...
dump((string) $this->stopwatch->getEvent('export-data')); // dumps e.g. '4.50 MiB - 26 ms'

You can also profile your template code with the stopwatch Twig tag:

ストップウォッチ Twig タグを使用して、テンプレート コードをプロファイリングすることもできます。
1
2
3
4
5
{% stopwatch 'render-blog-posts' %}
    {% for post in blog_posts %}
        {# ... #}
    {% endfor %}
{% endstopwatch %}

Profiling Categories

Use the second optional argument of the start() method to define the category or tag of the event. This helps keep events organized by type:

start() メソッドの 2 番目のオプション引数を使用して、イベントのカテゴリまたはタグを定義します。これにより、イベントをタイプ別に整理できます。
1
$this->stopwatch->start('export-data', 'export');

Profiling Periods

A real-world stopwatch not only includes the start/stop button but also a "lap button" to measure each partial lap. This is exactly what the lap() method does, which stops an event and then restarts it immediately:

実際のストップウォッチには、スタート/ストップ ボタンだけでなく、各部分ラップを測定するための「ラップ ボタン」も含まれています。これはまさに lap() メソッドが行うことであり、イベントを停止してからすぐに再開します。
1
2
3
4
5
6
7
8
9
10
11
12
$this->stopwatch->start('process-data-records', 'export');

foreach ($records as $record) {
    // ... some code goes here
    $this->stopwatch->lap('process-data-records');
}

$event = $this->stopwatch->stop('process-data-records');
// $event->getDuration(), $event->getMemory(), etc.

// Lap information is stored as "periods" within the event:
// $event->getPeriods();

Profiling Sections

Sections are a way to split the profile timeline into groups. Example:

セクションは、プロファイル タイムラインをグループに分割する方法です。例:
1
2
3
4
5
6
7
8
9
10
$this->stopwatch->openSection();
$this->stopwatch->start('validating-file', 'validation');
$this->stopwatch->stopSection('parsing');

$events = $this->stopwatch->getSectionEvents('parsing');

// later you can reopen a section passing its name to the openSection() method
$this->stopwatch->openSection('parsing');
$this->stopwatch->start('processing-file');
$this->stopwatch->stopSection('parsing');

All events that don't belong to any named section are added to the special section called __root__. This way you can get all stopwatch events, even if you don't know their names, as follows:

名前付きセクションに属さないすべてのイベントは、__root__ と呼ばれる特別なセクションに追加されます。このようにして、次のように名前がわからない場合でも、すべてのストップウォッチ イベントを取得できます。
1
2
3
foreach($this->stopwatch->getSectionEvents('__root__') as $event) {
    echo (string) $event;
}

Learn more