JSP の最適化

このセクションでは、JSP のレスポンス速度を向上させる方法について説明します。

JSP は最初にリクエストされたときにサーブレットにコンパイルされるので、その他の方法についてはサーブレットの最適化手法を参照してください。詳細については、 「サーブレットの最適化」 を参照してください。

JSP のプリコンパイル

デプロイ前にコンパイルされるサーブレットとは異なり、JSP ページは最初にリクエストされたときに JRun によってコンパイルされます。そのため、明らかな遅延が発生し、ユーザーによってはレスポンス速度が遅いと感じる可能性があります。JRun には、JSP をプリコンパイルするオプションがあります。

JSPC コンパイラは、Web サーバのコンテキストの外部で JSP をコンパイルするときに使用するコマンドラインツールです。JSPC コンパイラを使用すると、JSP のリクエスト時に JRun を使用して JSP をコンパイルするのではなく、コマンドラインから明示的に JSP をコンパイルできます。JSPC が <JRun のルートディレクトリ>/bin ディレクトリに置かれている場合は IBM jikes コンパイラを使用します。そうでない場合は、Sun javac コンパイラを使用します。

JSP をプリコンパイルする場合、これらのファイルの変更に対する JRun の自動検出機能を使用不可にしてください。詳細については、 「変更検出の無効化」 を参照してください。

メモ:  JSPC コンパイラは、JRun での JSP のコンパイルに使用されるコンパイラと同じコンパイラです。唯一異なる点は、JSPC コンパイラはコマンドラインから起動することです。

JSPC コンパイラの使用方法の詳細については、『JRun アセンブルとデプロイガイド』を参照してください。

変更検出の無効化

デフォルトでは、JRun が Web コンポーネントファイル (サーブレットや JSP など) を巡回し、最後の巡回時から変更があった場合にそれを検出します。この処理は、ホットデプロイや自動検出による変更を有効にするものです。ただし、このサイクルはパフォーマンスを低下させるため、運用環境では使用不可にしてください。 「JSP のプリコンパイル」 の説明にあるとおり、JSP をプリコンパイルする場合は特に不要です。

次の例に示すように、default-web.xml ファイルで JSPServlet の
translationDisabled 初期化パラメータを true に設定します。

<servlet>
   <servlet-name>JSPServlet</servlet-name>
   <servlet-class>jrun.jsp.JSPServlet</servlet-class>
   <load-on-startup>1</load-on-startup>
   <init-param>
     <param-name>keepGenerated</param-name>
     <param-value>false</param-value>
   </init-param>
   <init-param>
     <param-name>translationDisabled</param-name>
     <param-value>true</param-value>
   </init-param>  
 </servlet>

ServletContext オブジェクトでのスタティックデータのキャッシュ

ServletContext オブジェクトはオブジェクトを属性として保管します。ハッシュテーブルなどの構造のようなオブジェクトをキャッシュすることによって、アプリケーションの処理負荷を軽減できます。

JSP での暗黙のアプリケーションオブジェクトは、その JSP の ServletContext です。サーブレット内で実行する場合のように、ServletContext を取得するためのメソッドを実行する必要はありません。たとえば、次のコードによって JSP 内の ServletContext オブジェクトに属性を設定します。

application.setAttribute("statelist", qt);

JRun タグライブラリの jrun:sql タグを使用して QueryTable を取得する場合は、QueryTable オブジェクトをアプリケーションの属性として保管できます。ResultSet を Hashtable などの直列化可能なオブジェクトに変換する必要はありません。

ServletContext オブジェクトは、JSP に対してサーブレットの場合と同様に動作します。詳細については、 「ServletContext オブジェクトでのスタティックデータのキャッシュ」 を参照してください。

セッションの無効化

JSP がリクエストされるたびに、JRun は HttpSession オブジェクトを作成して、固有のクライアントごとにステートを維持します。JSP では、セッションデータは 暗黙のセッションオブジェクトとしてアクセス可能です。JSP では、セッションはデフォルトで有効になっています。

各セッションオブジェクトはサーバ上に保管されているため、システムリソースを少し使用します。さらに、セッションが有効になっている場合は、クライアントとサーバ間のトラフィックにセッション ID が含まれている必要があります。それによって、さらに小さいオーバーヘッドが発生します。

セッションを無効にするには、page ディレクティブを使用します。次の例のように、page ディレクティブの session 属性を false に設定します。

<%@ page session="false" %>

レスポンスオブジェクトのバッファーサイズの拡張

レスポンスオブジェクトのバッファーサイズを大きくして、ソケットの作成を減らします。

JSP レスポンスバッファーのデフォルトサイズは 8 KB です。レスポンスサイズが少なくともこのサイズに到達すると、JRun はバッファーをフラッシュします。次の例のように、バッファーに大きい値を設定し、必要なフラッシュ回数を減らします。

<%@ page buffer="16kb" %>

page ディレクティブは JSP ページ全体とそれに含まれているファイルに適用されます。

バッファーのサイズを確認するには、次の例のように、暗黙のレスポンスオブジェクトの getBufferSize メソッドを使用します。

バッファーサイズは <%= response.getBufferSize() %> です。

include の正しい使用方法

スタティックページを含める際は、できるだけ include アクションではなく include ディレクティブを使用します。include ディレクティブは、コンパイル時 (JSP の場合は最初にページがリクエストされたとき) に含まれたファイルの内容を挿入します。一方、include アクションは、実行時に (ページがリクエストされるたびに) 含まれたファイルをフェッチします。include アクションの方がサーバサイドでより多くの処理が必要です。

たとえば、スタティックファイル header.html がある場合は、次の例のように include ディレクティブを使用してファイルを含めます。

<%@ include file="/static-pages/header.html" %>

次の例のように include アクションを使用して、スタティックファイルをインクルードしないでください。

<jsp:include page="/static-pages/header.html" flush="true" />

SSI (Server-Side Include:サーバサイドインクルード) と include は同じタスクを実行しますが、JSP 内では SSI タグレットを使用しないでください。JRun では SSI をサポートしなくなりました。

出力をフラッシュしない

前バージョンの JRun (および以前の仕様に付属のサーブレットエンジン) では、include
アクションの実行後にバッファー出力をフラッシュする必要がありました。include アクションでは、必要な flush 属性を true に設定する必要がありました。JRun 4 では、この属性が false に設定されていて、自由に変更することができます。属性を false に設定することで、出力バッファーのフラッシュを遅らせることができます。ページのサイズにもよりますが、これで JSP のパフォーマンスが向上します。

次のコードは、include アクションの flush 属性が false に設定されていることを示しています。

<jsp:include page="myadditionalpage.jsp" flush="false" /> 

setProperty ショートカットの使用

JavaBeans は、JSP によって使用されるステート情報などのデータを保管します。フォーム変数を処理し、各入力フィールドを bean プロパティとして保管する作業は単調で、更新が難しく、ミスが発生する可能性があります。

フォームフィールドを JavaBean プロパティに設定する一般的な setProperty タグは次のとおりです。

<jsp:setProperty name="myBean" property="first_name" value="<%= 
request.getParameter("first_name") %>" />

JSP には、すべての bean プロパティを 1 つのタグで設定できるショートカットが用意されています。

jsp:setProperty タグがすべてのリクエストパラメータを反復処理し、パラメータ名および値のタイプが bean プロパティ名およびタイプと一致するように、property 属性を * に設定します。一致したプロパティはそれぞれ、対応するパラメータの値に設定されます。setProperty タグ内には value パラメータを指定しません。

property ワイルドカードの使用例を次に示します。

<jsp:setProperty name="myBean" property="*" />

パラメータ値を空の文字列 ("") に設定する場合、対応するプロパティは変更されません。リクエストパラメータに対応する bean プロパティがない場合、そのパラメータは無視されます。

jspInit でのスタティックデータのキャッシュ

クライアントが最初に JSP をリクエストしたとき、JRun は jspInit メソッドを呼び出します。このメソッドは、JSP ソースコードが変更された場合、または JRun サーバが再起動した場合のみ再び呼び出されます。jspInit メソッドはサーブレットの init メソッドに相当します。

JSP の jspInit メソッドをオーバーライドし、スタティックデータをこのメソッドに保管できます。一般的な例としては、データベースコネクションプールを作成し、初期化するタスクがあります。その他、アプリケーションのスコープに入っている初期化パラメータを取得するといったタスクも jspInit メソッド内で処理できます。

次のコードサンプルは、jspInit メソッド内の初期化パラメータを取得し、後で本文内で使用する JSP ページを示しています。

<%!
 String email;
 public void jspInit() {
  System.out.println("in jspInit()");
  javax.servlet.ServletConfig servletConfig = getServletConfig();
  email = 
servletConfig.getServletContext().getInitParameter("email");
}
%>
<HTML><BODY>
Email addy is:<%= email %>
</BODY></HTML>

次の例のように、web.xml ファイルの context-param ブロック内の初期化パラメータを定義します。

<web-app>
...
<context-param>
 <param-name>email</param-name>
 <param-value>webmaster@macromedia.com</param-value>
</context-param>
...
</web-app>

アプリケーションのスコープに入っている bean によるキャッシュ

bean のスコープを application に設定することは、JRun にとって現在のアプリケーションの bean のインスタンスが 1 つしかないことを意味します。

たとえば、データベースのステートおよびその短縮形のリストを選択し、その結果をアプリケーションのスコープに入っている bean にプロパティとして保管すると、ステートのフルネームをルックアップするたびにデータベースにクエリを実行する必要はありません。

その結果、ユーザーがサーバを再起動するまで、JRun はデータベースクエリを 1 回しか実行しません。次の例のように、bean にアクセスする任意の JSP は、bean のプロパティで取得できるようになります。

<jsp:usebean id="statelist" class="jrunsamples.optimize.StateList" 
scope="application" />
<jsp:setProperty name="statelist" property="*" />

bean のプロパティの 1 つであるステートにアクセスするには、次の行を使用します。

<jsp:getProperty name="statelist" property="MA" />

bean のスコープを sessionpage、または request に変更することもできます。bean のスコープを session に設定する場合は、page ディレクティブ内の sessions=true をオーバーライドしないでください。