0 follower

パフォーマンスチューニング

ウェブアプリケーションのパフォーマンスはさまざまな要因に影響されます。 データベースへのアクセス、ファイルシステム操作、ネットワークの帯域などはすべて潜在的影響要因です。 Yii はフレームワークによって生じるパフォーマンスへの影響をあらゆる側面に渡って少なくするよう努力していますが、そでもユーザアプリケーションにおいてはパフォーマンスを改善するさまざまな場所があります。

1. APC 拡張を有効にする

PHP APC 拡張 を有効にすることは、アプリケーションのパフォーマンスを改善する最も容易な手段でしょう。 APC は PHP の中間コードを最適化し、キャッシュすることで、リクエストごとに PHP スクリプトが解析されるのを避けます。

2. デバッグモードを無効にする

デバッグモードを無効にすることも、パフォーマンスを改善するもうひとつの簡単な方法です。 Yii アプリケーションは YII_DEBUG 定数が true に設定されていると、デバッグモードで動きます。 しかし、デバッグモードではいくつかのコンポーネントが余分な作業を発生させるので、パフォーマンスが低下します。 たとえば、メッセージロガーはあらゆるメッセージが記録される際に、追加のデバッグ情報も記録します。

3. yiilite.phpを使う

PHP APC 拡張 が有効である場合、yii.phpyiilite.php で置き換えることで、さらにパフォーマンスを改善できます。

yiilite.php はすべての Yii リリースに含まれています。 その内容は Yii の基本クラスをひとつにまとめたものです。 コメントとトレース命令はすべて取り除かれています。 したがって、yiilite.php を使うことで、インクルードされるファイルの数と、トレース命令の実行を減らすことになります。

APC 無しで yiilite.php を使うことはパフォーマンスを低下させる可能性があることに注意してください。 yiilite.php には必ずしもすべてのリクエストで必要ではないクラスが含まれており、追加の解析時間がかかります。 また、たとえ APC が有効であっても、サーバの設定によっては yiilite.php を使うとパフォーマンスが低下することがあります。 yiilite.php を使うかどうか決める最良の方法は、Yii フレームワークに同梱の hello world デモを使ってベンチマークをすることです。

4. キャッシュ機構を利用する

キャッシュ概要 の章で解説したように、Yii はいくつかのキャッシュソリューションを備えており、それらを利用することで、ウェブアプリケーションのパフォーマンスを大幅に改善できる可能性があります。 あるデータの生成に長い時間がかかっているなら、データキャッシュ を使ってデータ生成回数を減らすことができます。 ページの一部があまり変更されないなら、フラグメントキャッシュ を使って描画される回数を減らすことができます。 ページ全体があまり変更されないなら、ページキャッシュ を使ってページ描画コストを軽減できます。

アプリケーションで アクティブレコード を使っているなら、スキーマキャッシュを有効にして、データベーススキーマの解析時間を減らすべきです。 これは、CDbConnection::schemaCachingDuration プロパティを 0 以上の値にすることで可能です。

これらアプリケーションレベルのキャッシュテクニックとは別に、サーバレベルでのキャッシュソリューションを使ってアプリケーションのパフォーマンスを増加させることも可能です。 実のところ、先ほど述べた APC 拡張を有効にする はこのカテゴリに含まれます。 ほかにも2,3の例を挙げると、Zend Optimizer, eAccelerator, Squid といったものがあります。

5. データベースの最適化

データベースアクセスはウェブアプリケーションにおいてしばしば主なパフォーマンスボトルネックになります。 キャッシュを利用することで、パフォーマンスの頭打ちを軽減することはできるでしょうが、根本的な解決ではありません。 データベースとクエリを適切にデザインしないと、データベースに膨大なデータがあって、しかもキャッシュの有効期限が切れている場合、最新のデータを取得するのは法外なコストがかかります。

データベースのインデックスをかしこく作成しましょう。 インデックスを使えば、SELECT クエリはより速くなります。 ただし INSERT, UPDATE, DELETE クエリは遅くなるでしょう。

複雑なクエリには、PHP コードでクエリを発行して DBMS に解析を任せるより、データベースビューを作ることをすすめます。

アクティブレコード を使いすぎないでください。 アクティブレコード は OOP 流にデータをモデリングするには便利ですが、クエリ結果に対して一つまたは複数のオブジェクトを作る必要があるため、パフォーマンスを低下させます。 膨大なデータを扱うアプリケーションには、DAO を使うか、直接データベース API を使うのが賢明な選択でしょう。

言い忘れましたが、SELECT クエリで LIMIT を使ってください。 こうすることで、大量のデータが返されて、メモリを使い尽くすということがなくなります。

6. スクリプトファイルを最小化する

複雑なページでは、たくさんの外部 JavaScript ファイルや CSS ファイルを読み込む必要があります。 各ファイルを読み込むごとにサーバとの通信が発生するので、ファイルはなるべくまとめて少なくするべきです。 ファイルのサイズ自体を減らして、通信時間を減らすことも考えるべきでしょう。 このような作業を助けてくれるツールはたくさんあります。

Yii でページを表示する場合、コンポーネントが出力するファイルは変更したくない場合があるでしょう (例: コアコンポーネントやサードパーティコンポーネントなど)。 このようなファイルを最小化するため、二つのステップを踏む必要があります。

まず、clientScript コンポーネントの、scriptMap プロパティを設定することで、最小化するファイルを設定します。 これは PHP コードの中でも設定できます。 例:

$cs=Yii::app()->clientScript;
$cs->scriptMap=array(
    'jquery.js'=>'/js/all.js',
    'jquery.ajaxqueue.js'=>'/js/all.js',
    'jquery.metadata.js'=>'/js/all.js',
    ......
);

上記のコードが実行されると、これらの JavaScript ファイルは、/js/all.js という URL に割り当てられます。 これらの JavaScript ファイルのいずれかが必要になった場合、Yii は個別のファイルを読み込むのではなく、URL を一度だけ読み込みます。

次に、JavaScript ファイルをひとつのファイルにまとめる (そしておそらく圧縮する) ツールを使って、js/all.js というファイルを作ります。

CSS ファイルも同じようにします。

さらに、Google AJAX Libraries API を使って、ページのロード時間を改善することができます。 自分のサーバからではなく、Google のサーバから jquery.js を読み込むことができます。 そのために、まず scriptMap を以下のように設定します。

$cs=Yii::app()->clientScript;
$cs->scriptMap=array(
    'jquery.js'=>false,
    'jquery.ajaxqueue.js'=>false,
    'jquery.metadata.js'=>false,
    ......
);

こうすることで、Yii が個別のファイルを読み込むのを防ぎます。 代わりに以下のコードを明示的にページに記述します。

<head>
<?php echo CGoogleApi::init(); ?>
 
<?php echo CHtml::script(
    CGoogleApi::load('jquery','1.3.2') . "\n" .
    CGoogleApi::load('jquery.ajaxqueue.js') . "\n" .
    CGoogleApi::load('jquery.metadata.js')
); ?>
......
</head>

7. アセットをシンボリックリンクする

プロジェクトが多数のアセットファイルを使用する場合は、ファイルコピーの代りに シンボリックリンク を使うことでパフォーマンスをわずかに向上させることが出来ます。 アセットのシンボリックリンクを有効にするためには、protected/config/main.php 設定ファイルを使用して、 assetManager アプリケーション・コンポーネントの linkAssets プロパティを 設定しなければなりません。

return array(
    // ...
    'components' => array(
        // ...
        'assetManager' => array(
            'linkAssets' => true,
        ),
    ),
);

ただし、これ以外にも変更しなければならない設定があるかも知れない ということに注意して下さい。

Found a typo or you think this page needs improvement?
Edit it on github !