JSF视图在每个ajax请求上进行重建 [英] JSF view getting rebuild on each ajax request

查看:202
本文介绍了JSF视图在每个ajax请求上进行重建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm having a performance problem with my JSF/RichFaces/Facelets ajax requests and from what I can tell its because the entire component tree is being rebuild on each ajax request. This is happening even if I use ajaxSingle=true, wrap sections in a4j:region, declare a single section for rerendering or none at all. Our page is a dynamic page with many nested levels. The page may contain around 800-900 fields (inputText, rich calendars, selectOneMenus, etc). The initial load time is an issue, but I understand that issue, its a lot of fields. Once we have that initial build/render time though we have designed all other actions to be ajax and only reRender what is needed. From facelets debug logs I see messages like this on any ajax call:

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
RichFaces。 3.3.3.Final
Facelets 1.1.15
Seam 2.1.2

I'm not sure if something we are doing is causing the rebuild of the entire component tree, or facelets is determining this need required for some reason (stale cache?). Here is our stack: JBoss 5.1 JSF 1.2 RichFaces. 3.3.3.Final Facelets 1.1.15 Seam 2.1.2

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

I have tried adding some context parameters to see if they would help, but they did nothing: facelets.BUILD_BEFORE_RESTORE = false facelets.REFRESH_PERIOD = -1 or 5 (as in 5min)

无论如何都有告诉我们的观点是否正确缓存?我们没有delcare一个状态保存方法,所以我认为它默认为服务器端。我们所有的请求都发生在长时间运行的对话中。我不确定这是否会影响因为我认为视图会话缓存在会话级别?任何帮助将不胜感激,谢谢。

Is there anyway to tell if our views are being cached properly? We do not delcare a state saving method, so I believe it defaults to server side. All our requests happen within seam long running conversations. I wasn'te sure if this plays a factor as I thought views get cached at session level? Any help would be greatly appreciated, thank you.

更多调试后更新:

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

The AjaxViewHandler (which has a member variable of the FaceletsViewHandler) has developmentMode=true set. I'm not sure if this is causing facelets to not cache any views so any changes would be refreshed during development cycles...?? Its been very difficult to find any information on facelets/JSF caching of views and the behavior and controlling that. Furthermore, when I add config param:

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

这不需要!在调试器中,我仍然看到真正的设置。由于我们有很多子视图,我还尝试了
com.sun.faces.numberOfLogicalViews和
com.sun.faces.numberOfViewsInSession
从15上升到1000(默认值),这没有效果。

This did not take! In debugger I still see true set. Since we have a lot of subviews I also tried com.sun.faces.numberOfLogicalViews and com.sun.faces.numberOfViewsInSession to 1000 up from 15(default) and this had no effect.

我也试过改变客户端状态保存而没有任何运气。耗尽了想法....希望有人可以提供帮助....

I also tried changing to client side state saving without any luck. Running out of ideas....hope someone can help....

似乎Seam 2.1自动初始化RichFaces并且我不确定是否有什么要使用它.....

It seems Seam 2.1 auto-initializes RichFaces and I'm not sure if that has something to do with it.....

推荐答案

与任何性能问题一样,分析器可以帮助您找到瓶颈。 (是的,你知道它是restore_view阶段,但不是restore_view阶段的那个阶段。)

As with any performance problem, a profiler would help greatly in locating the bottlenecks. (Yes, you know it is the restore_view phase, but not where in the restore_view phase).

也就是说,恢复视图阶段确实恢复了整个视图,而不仅仅是将要处理或呈现的部分。引用 RichFaces taglib文档

That said, the restore view phase indeed restores the entire view, not just the parts that will be processed or rendered. Quoting the RichFaces taglib documentation:


进程:Id ['s](以调用UIComponent.findComponent()的格式)组件,在AjaxRequest引起的情况下在2-5阶段处理通过这个组件。可以是单个id,以逗号分隔的Id列表,或带有数组或集合的EL表达式

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.此外:

RESTORE_VIEW is phase 1. Also:


reRender:Id ['s](以调用UIComponent.findComponent()的格式)组件,在由此引起的AjaxRequest的情况下呈现零件。可以是单个id,以逗号分隔的Id列表,或带有数组或集合的EL表达式

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()使用比组件树更合适的数据结构来实现。 (在组件树中查找内容将归结为线性搜索...)。

Moreover, I am not sure that UIComponent.findComponent() is implemented using a more suitable datastructure than a component tree. (Finding something in the component tree would boil down to linear search ...).

我观察到与JSF 2.0(Mojarra)类似的效果。我的结论是,无论是否渲染,视图都不得包含超过十几个UIComponents。 (换句话说,AJAX不适合页面导航。)我们通过仅包含视图中当前可见的组件来缩小视图,并在需要显示许多新组件时切换视图。也就是说,我们有10个视图,每个视图只包含一个标签的内容,而不是一个包含10个标签的视图,每个视图包含30个组件。这种方法的一个缺点是在切换标签时会丢弃组件,导致任何没有保留在支持bean中的状态丢失。

I have observed similar effects with JSF 2.0 (Mojarra). My conclusion was that views must not contain more than a couple dozen UIComponents, irrespective of whether they are rendered. (Put differently, AJAX is unsuitable for page navigation.) We indend to keep views small by including only components that are currently visible in the view, and switch views if many new components need to appear. That is, instead of one view with 10 tabs with 30 components each, we'd have 10 views, each only containing the content of a single tab. A drawback of that approach is that components are disposed when switching tabs, causing any state not held in backing beans to be lost.

我不认为这是一个好的解。唉,这是我几周前看到的最好的一个。我也很高兴看到更好的一个。

I do not claim this to be a good solution. Alas, it was the best one I found when looking into this a couple weeks ago. I'd be happy to be shown a better one, too.

编辑
当我说恢复时,我的意思是 ViewHandler.restoreView(),它同时调用初始get请求和回发。说 restoreView 只是按原样重用现有视图是不正确的。例如,JSF 2.0规范要求见7.6.2.7节:]

Edit When I say restore, I mean ViewHandler.restoreView(), which called both for an initial get request and a postback. It is incorrect to say that restoreView would simply reuse an existing view as is. For instance, the JSF 2.0 spec mandates in section 7.6.2.7: ]


restoreView()方法必须履行以下职责:

The restoreView() method must fulfill the following responsibilities:

所有实施必须:


  • 如果无法识别viewId,则返回 null

  • 调用 restoreView()关联 StateManager 的方法,为
    传递 FacesContext 实例当前请求和计算出viewId,并返回返回的 UIViewRoot ,这可能是 null

  • 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节:


根据
javax.faces.STATE_SAVING_METHOD初始化参数的值,JSF实现支持两种保存状态的主要机制(请参见第11.1.3节应用程序配置
参数)。此参数的可能值给出了要使用的方法的一般指示,同时允许
JSF实现在技术细节上进行创新:

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 - 使保存的状态在请求之间存储在服务器上。希望启用
    其保存状态以故障转移到不同容器实例的实现必须在实现其服务器
    端状态保存策略时牢记这一点。默认实现在客户端和服务器模式下序列化视图。在
    服务器模式下,此序列化视图存储在会话中,并且用于检索视图的唯一键被发送到
    客户端。通过在会话中存储序列化视图,可以使用
    容器提供的常用机制进行故障转移。

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

Put differently, the AJAX support added to JSF (both the one added by RichFaces 3 to JSF 1.2, and the one incorporated into JSF 2.0) aims to reduce network bandwith consumption, not server side cpu consumption.

这篇关于JSF视图在每个ajax请求上进行重建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆