JSF ui:片段呈现性能 [英] JSF ui:fragment rendered performance

查看:92
本文介绍了JSF ui:片段呈现性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组jsf组件,这些组件是从一组excel文件中静态生成的(它们由业务人员更新)。每个生成的文件都代表一个业务对象,该业务对象的数据稍有不同,并且所有数据都属于同一类。

I have a set of jsf components that are statically generated from a set of excel files (they are updated by business people). Each generated file represents a business object that has slightly different data, and all of them belong to a same class.

为了动态呈现此数据,我找到了唯一的解决方案是要建立一堆 ui:fragment 并在运行时分派到正确的组件:

In order to render this dynamically, the only solution I found was to set up a bunch of ui:fragment and dispatch to the right component at runtime:





<!-- IMPLEMENTATION -->          
<composite:implementation> 
    <ui:fragment rendered="#{cc.attrs.type eq 'cartcred'}">
        <limites:limites-cartcred  limite="#{cc.attrs.limite}"/>
    </ui:fragment>
    <ui:fragment rendered="#{cc.attrs.type eq 'cdcp'}">
        <limites:limites-cdcp limite="#{cc.attrs.limite}"/>
    </ui:fragment>
    <ui:fragment rendered="#{cc.attrs.type eq 'cheqpredatado'}">
        <limites:limites-cheqpredatado limite="#{cc.attrs.limite}"/>
    </ui:fragment>
    <ui:fragment rendered="#{cc.attrs.type eq 'confirming'}">
        <limites:limites-confirming limite="#{cc.attrs.limite}"/>
    </ui:fragment>
   <!-- many more lines -->
   <!-- many more lines -->
   <!-- many more lines -->
    <ui:fragment rendered="#{cc.attrs.type eq 'contacorr'}">
        <limites:limites-contacorr limite="#{cc.attrs.limite}"/>
    </ui:fragment>

但是我发现这样的表现很糟糕。我坚信JSF仅会呈现单个组件,但似乎它正在呈现所有并在运行时隐藏其他组件。

But I found out that the perfomance of this is terrible. I tought that JSF would only render a single component, but it seems that it is rendering all of them and "hiding" the others at runtime.

是否有更有效的方式实现我的目标?我想根据有关业务类的运行时信息(很像if-then-else)呈现单个组件,但我只能确定在运行时呈现什么组件。

Is there a more efficient way of achieving my goal? I want to render a single component based on runtime information about a business class (much like an if-then-else), but I can only determine what is the component to render at runtime.

说明:
发生的情况是引用的每个组件limites:limites * 是一个庞大的复杂页面,其中包含许多其他组件。在运行时,名为 type'的参数将决定要呈现的组件。但是我的测试表明,如果我只渲染一个组件,而保留另一个 ui:fragments`(即使知道它们不会被渲染),它也会使很多变慢

Clarification: what happens is that each component referenced by limites:limites* is a huge complex page with lots of other components. At runtime, the parameter named type' will decide what component to render. But my tests show that if I only render one component, but leave the otherui:fragments` (even knowing that they will not be rendered), it will render much slower than if I remove the components.

因此,如果我的页面正是这样:

So if my page is exactly like this:

<composite:interface>
    <composite:attribute name="type" required="true" />
    <composite:attribute name="limite" required="true" />
</composite:interface>         
<composite:implementation> 
    <ui:fragment rendered="#{cc.attrs.type eq 'cartcred'}">
        <limites:limites-cartcred  limite="#{cc.attrs.limite}"/>
    </ui:fragment>
</composite:implementation>

它将使很多(大约10倍)比初始版本快,即使参数相同。我怀疑JSF会创建整个组件树,并且仅在运行时才会决定(取决于所提供的参数)是否相互渲染。

it will render much (around 10x) faster than the initial version, even though the parameters are the same. I suspect that JSF will create the entire component tree and only at runtime it will decide (depending on the supplied parameter) if it will render each other or not.

编辑

几乎在那里。我只需要包含我的复合组件 动态。我尝试评估ELExpression,但没有用。我需要的是一种在组件创建过程中访问当前作用域的方法,并使用该作用域生成正确的文件名:

Almost there. I just need to include my composite component dynamically. I tried evaluating an ELExpression but that didn't work. What I need is a way of accessing the current scope within the component creation, and using that to generate the proper file name:

//obviously, ELExpressions don't work here
Resource resource = application.getResourceHandler().createResource("file-#{varStatus.loop}.xhtml", "components/dynamicfaces");


推荐答案

一种可能是使用 binding 属性可从托管Bean内部访问容器
组件,并从
Java端构建组件树。这样,您可以只包含所需的组件,根本不需要评估
组件。

One possibility might be to use the binding attribute to access a container component from inside your managed bean and build the component tree from the java side. That way you could include only the needed components, unneeded components won't be evaluated at all.

JSP:

<h:panelGroup binding="#{managedBean.panel}"/>

托管Bean:

private UIPanel panel;

// getter and setter


// Action method, might also work in a @PostConstruct
public String showComponent() {
    if (showComponent1) {
        UIOutput component1 = new HtmlOutputText();
        component1.setValue("Hello world!");

        getPanel().getChildren().add(component1);
    }

    return "viewId";
}

我还没有将其与复合组件一起使用,这个问题似乎有更多详细信息和示例应用程序有关与复合组件一起使用的示例。

I haven't used this together with composite components yet, this question seems to have some more details and an example application regarding using this with composite components.

编辑:关于您的编辑,您可以还可以像这样评估托管bean中的EL表达式:

Regarding your edit, you can also evaluate EL expressions in your managed bean like this:

FacesContext facesContext = FacesContext.getCurrentInstance();
ELContext elContext = facesContext.getELContext();
ExpressionFactory exprFactory = facesContext.getApplication().getExpressionFactory();
ValueExpression expr = exprFactory.createValueExpression(elContext, "#{expr}", String.class);
String value = (String) expr.getValue(elContext);

这篇关于JSF ui:片段呈现性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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