草庐IT

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

coder 2023-09-02 原文

我的 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 - JSF View 在每个 ajax 请求上得到重建的更多相关文章

  1. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  2. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  3. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  4. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  5. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  6. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  7. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

    这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

  8. 【Java 面试合集】HashMap中为什么引入红黑树,而不是AVL树呢 - 2

    HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候

  9. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

  10. java - 为什么 ruby​​ modulo 与 java/other lang 不同? - 2

    我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.

随机推荐