Java JSF性能

Java JSF性能,java,jsf,richfaces,Java,Jsf,Richfaces,我是JSF编程新手,设计了一个相当简单的JSF2.0Web应用程序。它的特点是左侧有一个rich:树,它充当分层菜单。当用户单击树中的某个内容时,将启动一个选择处理程序,并触发页面的部分重新加载,其中显示与您刚才单击的内容相关的内容 问题是界面感觉很迟钝,所以我启用了一些日志记录,并添加了一个自定义阶段侦听器,让我知道瓶颈在哪里 2012-05-21 07:58:05.516 DEBUG NodeBean - Retrieving properties 2012-05-21 07:58:05.5

我是JSF编程新手,设计了一个相当简单的JSF2.0Web应用程序。它的特点是左侧有一个rich:树,它充当分层菜单。当用户单击树中的某个内容时,将启动一个选择处理程序,并触发页面的部分重新加载,其中显示与您刚才单击的内容相关的内容

问题是界面感觉很迟钝,所以我启用了一些日志记录,并添加了一个自定义阶段侦听器,让我知道瓶颈在哪里

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是一个请求范围的bean,它有一个“getProperties()”方法。我不知道为什么会在一开始调用它,但它的开销很小,所以这是另一次的问题

正如您所见,JSF生命周期需要很长时间才能完成,而定制代码的开销相当小。通过谷歌搜索,我发现“immediate='true'”可以让您跳过一些步骤,但将其添加到rich:tree中没有效果。我认为我做错了什么,但就我个人而言,我不知道是什么

旁注:有时(通常在用户不活动之后),进程会在第3阶段后停止,这意味着没有内容返回给用户。在用户重新加载页面之前,rich:树中的任何选择都将具有相同的行为

编辑:

在进一步调试之后,richfaces树似乎会在每个请求上重建几次。这与这个问题有关:

我的用例是:树基本上是静态的,如果您选择一个项目,与该项目相关的属性和内容应该显示在右侧。因此,基本上我有一个selectionchange监听器,它注册您选择的内容,还有一个中心组件的重新呈现器,它使用该设置加载属性和内容。这棵树(几乎)永远不会被刷新。但实际发生的是,整个树都是为第2、3、4和6阶段重建的,即使部分重新渲染器没有提及或引用该树

最初,我有这样的想法:

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

我已经为我的特定用例解决了这个问题,尽管我不确定它对其他人有多适用。我已从以下位置更新了org.richfaces.component.TreeRange.shouldIterateChildren()方法:

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

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

    return traverseAll || tree.isExpanded();
}
致:


我仍然不知道我是否使用rich:tree是错误的,或者它实际上是一个bug,我已经向jboss用户邮件列表发送了一封邮件,如果它被证明是一个bug,我将创建一个jira问题。至少现在我的web应用程序响应速度很快,即使有一棵大树。

我已经解决了我的特定用例的问题,尽管我不确定它是否适用于其他用例。我已从以下位置更新了org.richfaces.component.TreeRange.shouldIterateChildren()方法:

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

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

    return traverseAll || tree.isExpanded();
}
致:


我仍然不知道我是否使用rich:tree是错误的,或者它实际上是一个bug,我已经向jboss用户邮件列表发送了一封邮件,如果它被证明是一个bug,我将创建一个jira问题。至少现在我的web应用程序响应速度很快,即使有一棵大树。

Try mode=“client”。您真的需要服务器往返吗?immediate=true将绕过验证并不会更新bean,但您只希望在取消页面上的操作时执行这些操作我不完全知道在哪里设置属性?富目录树配置为toggleType=“client”和selectionType=“ajax”。但无论采用哪种方式检索内容,都必须往返到服务器。我认为@EJP意味着在客户端或服务器上保存状态啊,你是指“javax.faces.state\u saving\u METHOD”上下文参数?它确实设置为“服务器”。有一个不可序列化的应用程序范围bean,它在设置为client(PS:web应用程序仅由少数人使用)Try mode=“client”时抛出异常。您真的需要服务器往返吗?immediate=true将绕过验证并不会更新bean,但您只希望在取消页面上的操作时执行这些操作我不完全知道在哪里设置属性?富目录树配置为toggleType=“client”和selectionType=“ajax”。但无论采用哪种方式检索内容,都必须往返到服务器。我认为@EJP意味着在客户端或服务器上保存状态啊,你是指“javax.faces.state\u saving\u METHOD”上下文参数?它确实设置为“服务器”。有一个不可序列化的应用程序范围bean,当设置为client时会抛出一个异常(PS:web应用程序只被少数人使用)
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();
    }
}