java - JSF View 在每个 ajax 请求上得到重建

标签 java jsf richfaces facelets

我的 JSF/RichFaces/Facelets ajax 请求出现了性能问题,据我所知,因为整个组件树都在每个 ajax 请求上重建。即使我使用 ajaxSingle=true,在 a4j:region 中包装部分,声明一个单独的部分用于重新渲染或根本不声明,也会发生这种情况。我们的页面是一个具有许多嵌套级别的动态页面。该页面可能包含大约 800-900 个字段(inputText、丰富的日历、selectOneMenus 等)。初始加载时间是一个问题,但我理解这个问题,它涉及很多领域。一旦我们有了初始构建/渲染时间,尽管我们已经将所有其他操作设计为 ajax,并且只重新渲染需要的内容。从 facelets 调试日志中,我在任何 ajax 调用中看到这样的消息:

2011-08-24 22:19:03,054 DEBUG [facelets.viewhandler] (http-0.0.0.0-8080-2) Took
24445ms to build view: /oconsole/appfile.xhtml
2011-08-24 22:19:09,377 DEBUG [facelets.viewhandler] (http-0.0.0.0-8080-2) Took
6323ms to render view: /oconsole/appfile.xhtml

我不确定我们正在做的事情是否会导致整个组件树的重建,或者 facelets 是否出于某种原因(陈旧的缓存?)确定了此需求。这是我们的堆栈: JBoss 5.1 JSF 1.2 丰富的面孔。 3.3.3. final Facelets 1.1.15 接缝 2.1.2

我尝试添加一些上下文参数以查看它们是否有帮助,但它们什么也没做: facelets.BUILD_BEFORE_RESTORE = 假 facelets.REFRESH_PERIOD = -1 或 5(如 5 分钟)

有没有办法判断我们的 View 是否被正确缓存?我们不关心状态保存方法,所以我相信它默认为服务器端。我们所有的请求都发生在接缝长时间运行的对话中。我不确定这是否是一个因素,因为我认为 View 是在 session 级别缓存的?任何帮助将不胜感激,谢谢。

更多调试后更新:

AjaxViewHandler(它有一个 FaceletsViewHandler 的成员变量)设置了 developmentMode=true。我不确定这是否会导致 facelets 不缓存任何 View ,因此任何更改都会在开发周期中刷新...??很难找到有关 View 的 facelets/JSF 缓存及其行为和控制的任何信息。此外,当我添加配置参数时:

<context-param>
<param-name>facelets.DEVELOPMENT</param-name>
<param-value>false</param-value>
</context-param>

这个没带!在调试器中,我仍然看到 true 集。因为我们有很多 subview 我也试过了 com.sun.faces.numberOfLogicalViews 和 com.sun.faces.numberOfViewsInSession 从 15(默认)增加到 1000,这没有任何效果。

我也尝试过更改为客户端状态保存,但没有任何运气。想法用完了……希望有人能帮忙……

似乎 Seam 2.1 会自动初始化 RichFaces,我不确定这是否与它有关......

最佳答案

与任何性能问题一样,分析器将极大地帮助定位瓶颈。 (是的,你知道它是 restore_view 阶段,但不是在 restore_view 阶段的 where)。

也就是说,恢复 View 阶段确实恢复了整个 View ,而不仅仅是将要处理或渲染的部分。引用 RichFaces taglib documentation :

process: Id['s] (in format of call UIComponent.findComponent()) of components, processed at the phases 2-5 in case of AjaxRequest caused by this component. Can be single id, comma-separated list of Id's, or EL Expression with array or Collection

RESTORE_VIEW 是第 1 阶段。另外:

reRender: Id['s] (in format of call UIComponent.findComponent()) of components, rendered in case of AjaxRequest caused by this component. Can be single id, comma-separated list of Id's, or EL Expression with array or Collection

此外,我不确定 UIComponent.findComponent() 是使用比组件树更合适的数据结构实现的。 (在组件树中查找某些东西将归结为线性搜索......)。

我在 JSF 2.0 (Mojarra) 中观察到类似的效果。我的结论是 View 不能包含超过几十个 UIComponents,无论它们是否被渲染。 (换句话说,AJAX 不适合页面导航。)我们打算通过仅包含 View 中当前可见的组件来保持 View 较小,并在需要显示许多新组件时切换 View 。也就是说,我们有 10 个 View ,每个 View 只包含一个选项卡的内容,而不是一个 View 有 10 个选项卡,每个选项卡有 30 个组件。这种方法的一个缺点是组件在切换选项卡时会被释放,导致任何未保存在支持 bean 中的状态都将丢失。

我并不认为这是一个好的解决方案。 las,这是我几周前调查时发现的最好的一个。我也很乐意看到更好的。

编辑 当我说恢复时,我指的是 ViewHandler.restoreView(),它同时调用初始获取请求和回发。说 restoreView 只是按原样重用现有 View 是不正确的。例如,JSF 2.0 规范在第 7.6.2.7 节中要求:]

The restoreView() method must fulfill the following responsibilities:

All implementations must:

  • If no viewId could be identified, return null.
  • Call the restoreView() method of the associated StateManager , passing the FacesContext instance for the current request and the calculated viewId, and return the returned UIViewRoot, which may be null.

在第 7.7.2 节中:

JSF implementations support two primary mechanisms for saving state, based on the value of the javax.faces.STATE_SAVING_METHOD initialization parameter (see Section 11.1.3 “Application Configuration Parameters”). The possible values for this parameter give a general indication of the approach to be used, while allowing JSF implementations to innovate on the technical details:

  • client -- [...]
  • server -- Cause the saved state to be stored on the server in between requests. Implementations that wish to enable their saved state to fail over to a different container instance must keep this in mind when implementing their server side state saving strategy. The default implementation Serializes the view in both the client and server modes. In the server mode, this serialized view is stored in the session and a unique key to retrieve the view is sent down to the client. By storing the serialized view in the session, failover may happen using the usual mechanisms provided by the container.

换句话说,添加到 JSF 中的 AJAX 支持(RichFaces 3 添加到 JSF 1.2 中的一种,以及合并到 JSF 2.0 中的一种)旨在减少网络带宽消耗,而不是服务器端 cpu 消耗。

关于java - JSF View 在每个 ajax 请求上得到重建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7190225/

相关文章:

java - Jmap堆转储,它包括年轻一代吗?

java - 许多类引用数据库连接类的最佳方式

java - jsf中的响应编写器

javascript - JSF 调用支持 bean 方法并在 ENTER 键上重新呈现组件

java - 丰富 :pickList selection buttons arrow in right-to-left language direction

jsf-2 - RichFaces 中的 session 空指针

java - JAX-WS 在客户端检索抛出的自定义异常

java - 使用计数数组来保存另一个数组的计数

jsf - 如何在Tomcat上安装和使用CDI?

java - 当我启动 tomcat 时,我的 java 应用程序一直一遍又一遍地开始