1

私はJSFプログラミングに不慣れで、かなり単純なJSF2.0Webアプリケーションを設計しました。左側に階層メニューとして機能するrich:treeがあります。ユーザーがツリー内の何かをクリックすると、選択ハンドラーが起動され、ページの部分的な再読み込みがトリガーされ、クリックした内容に関連するコンテンツが表示されます。

問題は、インターフェイスが遅く感じられることです。そこで、ロギングを有効にし、カスタムフェーズリスナーを追加して、ボトルネックがどこにあるかを把握できるようにしました。

2012-05-21 07:58:05.516 DEBUG NodeBean - Retrieving properties
2012-05-21 07:58:05.516 DEBUG CustomPhaseListener - Before phase: APPLY_REQUEST_VALUES 2
2012-05-21 07:58:05.876 DEBUG RepositoryBean - Selection change event invoked (size: 1)
2012-05-21 07:58:05.876 DEBUG RepositoryBean - Selection change event handled
2012-05-21 07:58:05.876 DEBUG CustomPhaseListener - After phase: APPLY_REQUEST_VALUES 2
2012-05-21 07:58:05.876 DEBUG CustomPhaseListener - Before phase: PROCESS_VALIDATIONS 3
2012-05-21 07:58:06.469 DEBUG CustomPhaseListener - After phase: PROCESS_VALIDATIONS 3
2012-05-21 07:58:06.469 DEBUG CustomPhaseListener - Before phase: UPDATE_MODEL_VALUES 4
2012-05-21 07:58:06.844 DEBUG CustomPhaseListener - After phase: UPDATE_MODEL_VALUES 4
2012-05-21 07:58:06.844 DEBUG CustomPhaseListener - Before phase: INVOKE_APPLICATION 5
2012-05-21 07:58:06.844 DEBUG CustomPhaseListener - After phase: INVOKE_APPLICATION 5
2012-05-21 07:58:06.860 DEBUG CustomPhaseListener - Before phase: RENDER_RESPONSE 6
2012-05-21 07:58:06.985 DEBUG NodeBean - Retrieving properties
2012-05-21 07:58:07.001 DEBUG RepositoryBean - Retrieving content
2012-05-21 07:58:07.001 DEBUG RepositoryBean - Content retrieved
2012-05-21 07:58:07.376 DEBUG CustomPhaseListener - After phase: RENDER_RESPONSE 6

NodeBeanは、「getProperties()」メソッドを持つリクエストスコープのBeanです。なぜ最初に呼び出されているのかわかりませんが、オーバーヘッドが最小限であるため、別の機会に問題になります。

ご覧のとおり、JSFのライフサイクルは完了するまでに何年もかかりますが、カスタムコードはオーバーヘッド的にはかなり些細なものです。グーグルした後、「immediate ='true'」を使用するといくつかの手順をスキップできることがわかりましたが、rich:treeに追加しても効果はありません。私は何か間違ったことをしていると思いますが、私の人生のために、私は何を理解することができません。

補足:時々(通常はユーザーが操作を行わなかった後)、プロセスはフェーズ3の後で停止します。これは、コンテンツがユーザーに返されないことを意味します。rich:treeでの選択は、ユーザーがページをリロードするまで同じ動作をします。

編集:

さらにデバッグした後、richfacesツリーはリクエストごとに数回再構築されているようです。これはこの問題に関連しています:JSF2 Richfaces4.1.0Ajaxツリーの部分レンダリング

私のユースケースは次のとおりです。ツリーはほとんど静的であり、アイテムを選択すると、そのアイテムに関連するプロパティとコンテンツが右側に表示されます。つまり、基本的に、選択したものを登録するselectionchangeリスナーと、その設定を使用してプロパティとコンテンツをロードする中央コンポーネントの再レンダリングがあります。ツリーは(ほとんど)決して更新されるべきではありません。実際に発生するのは、部分的な再レンダリングでツリーについて言及または参照していなくても、ツリー全体がステージ2、3、4、および6で再構築されることです。

最初に私はこれを持っていました:

<rich:tree id="tree" var="node"
        value="#{repository.browser}" 
        render="node" 
        toggleType="client" selectionType="ajax"

「selectionType」をclientに設定すると、問題は解消されますが、バックエンドで再レンダリングまたは呼び出されることはありません。次のようなものを追加してみました

<f:ajax event="click" render=":node"/>

しかし、それも失敗しました(ツリーはまだバックグラウンドで再構築されていました)。ツリーをキャッシュする方法はありますか、それともリクエストごとにツリーを再構築しない方法はありますか?

4

1 に答える 1

1

他のユースケースにどの程度適用できるかはわかりませんが、特定のユースケースの問題を修正しました。org.richfaces.component.TreeRange.shouldIterateChildren()メソッドを次の場所から更新しました。

public boolean shouldIterateChildren() {
    if (tree.getRowKey() == null) {
        return true;
    }

    if (tree.isLeaf()) {
        return false;
    }

    return traverseAll || tree.isExpanded();
}

に:

public boolean shouldIterateChildren() {
    if (tree.isLeaf())
        return false;
    else {
        char separatorChar = UINamingContainer.getSeparatorChar(FacesContext.getCurrentInstance());
        String clientId = tree.getClientId();
        boolean render = false;
        for (String idToRender : FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds()) {
            // render the tree if you explicitly mention either the client id (e.g. "menuForm:tree") or the parent component client id (e.g. "menuForm")
            // note that when clicking on an object in the tree, the following render target is requested: menuForm:tree@selection
            if (clientId.equals(idToRender) || clientId.matches(idToRender + separatorChar + ".*")) {
                render = true;
                break;
            }
        }
        // always render if it's not a postback
        return render || !FacesContext.getCurrentInstance().isPostback();
    }
}

rich:treeを間違って使用しているかどうか、または実際にバグであるかどうかはまだわかりません。jboss-usersメーリングリストにメールを送信しました。実際にバグであることが判明した場合は、jiraの問題が発生します。少なくとも今では、私のWebアプリケーションは大きなツリーでもすばやく応答します。

于 2012-05-22T13:39:50.083 に答える