简体   繁体   English

通过一种替代方法来减少JSF组件树/状态。 可以吗

[英]Reducing the JSF component tree/state by an alternate approach. Is it Okay?

Unfortunately, I made a mistake of choosing JSF for an internet facing, high traffic application, now I am wondering as to how to improve the scalability of this JSF webapp. 不幸的是,我为面向互联网,高流量的应用程序选择JSF犯了一个错误,现在我想知道如何提高此JSF Web应用程序的可伸缩性。

I have a JSF page that displays a large no of items each of which may be commented upon. 我有一个JSF页面,其中显示了大量项目,每个项目都可能被评论。 Inorder to reduce the state & improve performance I am trying to reduce the no of forms / commandButtons on the page. 为了减少状态并提高性能,我正在尝试减少页面上的forms / commandButtons

1. Through what ways can I reduce the component tree/ statefulness of JSF ? 1.我可以通过哪些方法来降低JSF的组件树/有状态性? Do the plain html elements(that are mixed in between the jsf tags) also form part of component tree ? 普通的html元素(混合在jsf标签之间)是否也构成了组件树的一部分? I dont know how component state saving has been helpful to my app since I have been following plain request/response model while designing my app, (may be it is helpful for just JSF's internal requirements)!? 我不知道保存组件状态对我的应用程序有何帮助,因为我在设计应用程序时一直遵循简单的请求/响应模型,(也许这对JSF的内部需求很有帮助)!

2. I was thinking of an approach where instead of creating a separate <h:form> (each with a separate commandButton ) for every item like below, 2.我在考虑一种方法,而不是为下面的每个项目创建一个单独的<h:form> (每个都带有一个单独的commandButton ),

(Usual Approach) (常用方法)

 <h:form> <!-- for each item a separately --> <h:outputText value="Add comment"/> <h:inputTextarea value="#{itemController.comment}" required="true"/> <p:commandButton actionListener="#{itemController.addUserComment(123)}" value="Add" /> </h:form> 

(Alternate Approach) (替代方法)

I am trying to make the above better by just putting a single remoteCommand for all the items & pass the required parameters to this remoteCommand. 我试图通过仅对所有项目放置单个remoteCommand并将所需参数传递到此remoteCommand来使上述效果更好。

 <form> <input id="item1_comment"/> <button onclick="addComment(123, 'item1_comment');"/> </form> <script type="text/javascript"> function addComment(itemId, id) { $('#comment_in').attr('value', $('#'+id).attr('value')); $('#forItem_in').attr('value', itemId); addComment_RC(); // call remoteCommand to show the content in dialog } </script> <h:form prependId="false" > <!-- for all items, just single remoteCOmmand --> <h:inputHidden id="comment_in" value="#{itemController.comment}"/> <h:inputHidden id="forItem_in" value="#{itemController.forItem}"/> <p:remoteCommand name="addComment_RC" process="@form" actionListener="#{itemController.addComment()}" /> </h:form> 

Is it better to do it this way (or are there any issues with this approach)? 这样做是否更好(或者这种方法有任何问题)?

Performance issues in the situation you describe are often caused by the large number of EL expressions , That burdens the server. 您描述的情况下的性能问题通常是由大量EL表达式引起的,这给服务器造成了负担。

One approach to tackle this issue is to compute the comments on the client side, and pass them all at once to the server. 解决此问题的一种方法是在客户端计算注释,然后将所有注释立即传递给服务器。 Thus reducing the number of comment EL expression to one or none, and use only one button. 因此, 将注释EL表达式的数量减少为一个或一个,并且仅使用一个按钮。

Place all the elements in one form. 将所有元素放在一种形式中。 The comments fields are not binded. 注释字段未绑定。

  <h:form>

       // first element 
       <h:outputText value=#{first element}
       // first comment 
       <h:inputTextarea id="comment1"/> <-- notice there is no EL expression 
                                            But we use a unique id for each comment 

       // second element 
       <h:outputText value=#{second element}
       // second comment 
       <h:inputTextarea id="comment2"/> 
       .
       .
       .



</h:form>

From here you could either 从这里你可以

1. after each blur event in any of the comment fields, ajax the server and pass as parameters the comment and the id of the comment from which the ajax call was made. 1.在任何注释字段中的每个模糊事件之后,对服务器进行ajax处理,并将注释和进行ajax调用的注释ID作为参数传递。 on the server update your model accordingly 在服务器上相应地更新您的模型

Or You can also gather all the comments on the client side and send them to the server at one time. 或者,您也可以在客户端收集所有注释,然后一次将它们发送到服务器。

2. When the user press the submit button call a js function to aggregate all the comments in a structure that you will be able to parse easily on the server side (ie. "{c1,comment a};{c2,comment b};{c5=,comment e}..." ). 2.当用户按下“提交”按钮时,调用js函数将所有注释聚合为一个结构,您可以在服务器端轻松解析该结构(即"{c1,comment a};{c2,comment b};{c5=,comment e}..." )。 pass that string to the server, parse it and update your model accordingly. 将该字符串传递给服务器,进行解析并相应地更新模型。

3. after each blur event in any of the comment fields, call a js function that updates an hidden field. 3.在任何注释字段中的每个模糊事件之后,调用js函数来更新隐藏字段。

<h:inputHidden value="{myClass.allComments}" />

when the user submits the form parse allComments and update your model accordingly. 当用户提交表单时,解析allComments并相应地更新您的模型。

EDIT: 编辑:

To address the general performance issue I've added recommendations from an article that I found helpful speed up part 1 Speed up part 2 . 为了解决一般的性能问题,我在一篇文章中添加了一些建议,这些文章对加快第1部分的 速度有所帮助。

Hope this helps 希望这可以帮助

btw, I would recommend the first approach rather than the last two. 顺便说一句,我建议第一种方法,而不是后两种。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM