我们的应用程序性能有问题。我们正在使用客户端STATE_SAVING_METHOD。我在游乐场项目上做了一些测试,发现根本原因是我们正在大量使用的复合组件。
让我介绍一下我的测试用例:
<h:form>
<p:outputLabel value="Test input"/>
<p:inputText id="testInputTextId"
value="#{customerController.someTestValue}">
<p:ajax event="click" update="testInputTextId" listener="#{customerController.increaseValue()}"
process="@this" partialSubmit="true"/>
</p:inputText>
</h:form>
<h:form>
<c:forEach begin="0" end="5000" varStatus="loop">
<!-- specific code -->
</c:forEach>
</h:form>
CustomerController只有int成员,其方法是增加其值。我用c:forEach标签来模拟大视图。
第一个示例(没有复合组件)按预期工作,只需将注释替换为:
<p:panelGrid>
<p:row>
<p:column>
<p:outputLabel value="Label(A) #{loop.index}"/>
</p:column>
<p:column>
<p:inputText value="Value #{loop.index}"/>
</p:column>
</p:row>
</p:panelGrid>
第二个例子是相同的,但提到的代码在复合组件中:
<ui:component xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute name="label" required="true" type="java.lang.String"/>
</composite:interface>
<composite:implementation>
<p:panelGrid>
<p:row>
<p:column>
<p:outputLabel value="Label(B) #{cc.attrs.label}"/>
</p:column>
<p:column>
<p:inputText value="Value #{cc.attrs.label}"/>
</p:column>
</p:row>
</p:panelGrid>
</composite:implementation>
</ui:component>
所以用
替换评论<cc:testInputCompositeComponent label="#{loop.index}"/>
Tomee 1.5.2(JSF 2.1.29-03,PrimeFaces 5.2.3,JDK 64 1.7.0_67)
简单页面:
复合组件:
使用facelet标记文件:
Tomee 1.7.1(JSF 2.1.29-03,JSF 2.2.11,PrimeFaces 5.2.3,JDK 64 1.7.0_67)
简单页面:
复合组件:
使用facelet标记文件:
GlassFish 4.1(JSF 2.2.11,PrimeFaces 5.2.3,JDK 64 1.8.0_45)
简单页面:
复合组件:
使用facelet标记文件:
因此,当使用复合组件时,流量会大50倍。在本地ENV上,这不是一个大问题,但在现实世界中,客户端和服务器距离很远,导致用户需要等待3-5秒才能进行非常简单的操作,其中只需根据用户操作更新一个组件。请注意,我基本上不对第二种形式做任何事情,只想在第一种形式更新组件。
请问,有人知道这是否已知问题?或者我有什么不对劲?谢谢。
[更新]根据BalusC评论,我还使用Facelet标记文件进行了测试,并将结果添加到原始帖子中。
使用最新的浏览器来测量:Opera,Firefox
有一些有趣的数字: