2011-05-16 49 views
2

我有一組jsf組件,它們是從一組excel文件(它們由業務人員更新)靜態生成的。每個生成的文件都代表一個具有稍微不同數據的業務對象,並且它們都屬於同一個類。JSF UI:片段呈現性能

爲了動態渲染這個,我發現的唯一的解決辦法是設置了一堆ui:fragment和調度,以正確的組件在運行時:

<!-- 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只會渲染一個組件,但它似乎是渲染它們並在運行時隱藏其他組件。

有沒有更高效的方法來實現我的目標?我想根據有關業務類的運行時信息(很像if-then-else)來渲染單個組件,但我只能確定在運行時渲染哪個組件。


澄清: 發生的事情是由limites:limites*引用的每個組件是與許多其他組件的龐大複雜的頁面。在運行時,名爲type' will decide what component to render. But my tests show that if I only render one component, but leave the other ui:fragments`的參數(即使知道它們不會被渲染),它將比我刪除組件時慢得多地顯示

所以,如果我的網頁是完全一樣:

<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會創建整個組件樹,並且只有在運行時纔會決定(取決於提供的參數)它是否會呈現對方。


編輯

幾乎沒有。我只需要包括我的複合組件動態。我試着評估一個ELExpression,但沒有奏效。我需要的是訪問該組件創建中的電流範圍,並用它來生成正確的文件名的方法:

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

回答

2

一種可能性是使用binding屬性從內部訪問容器 組件您的託管bean並從java端的 構建組件樹。這樣您就可以只包含所需的組件,不需要的組件將不會被評估。

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"; 
} 

我還沒有和複合組件一起使用這個呢,this question似乎有一些更多的細節和example application使用這種複合有關組件。

編輯:關於你的編輯,也可以求EL表達式在你的託管bean是這樣的:

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); 
+0

這工作,雖然它沒有解決我的特殊問題,我認爲這是一個正確的答案。 – 2011-05-18 14:52:06

+0

@Miguel,謝謝,請參閱我的更新瞭解如何從java代碼中使用el表達式的示例。 – 2011-05-18 15:04:34

+0

赫赫謝謝,我已經嘗試評估bean上的ELExpression,但由於某種原因,它沒有正確評估;它可能無法解決我在調用'setComponent'時嘗試訪問的變量。有時你只需要繼續前進。 – 2011-05-19 12:43:42

8

是的,rendered屬性評估過程中渲染時間,而不是在編譯時間。是的,這是相當可怕的。設想一個這樣的條件花費1ms,評估其中10個將總共花10倍,10ms。如果您在分頁表中有十個這樣的組件,那麼webapp加載時間將會延長0.1秒。關於一個眨眼更長。但是,如果您不分頁和/或使用MSIE作爲參考瀏覽器,則需要更長的時間。您是否在適當的瀏覽器中對數據進行分頁並進行測試?

最好你可以做的是用JSTL標籤替換<ui:fragment>,比如<c:if>/<c:choose>,這樣它就可以在構建期間評估,而不是在渲染期間評估。或者,也可以在後臺bean構造器中而不是在視圖中構建組件樹。

+0

我無法分頁,因爲生成的頁面正在用於打印目的。由於上面的頁面也是從xls元數據生成的,我真正想知道的是如何確保只有在呈現條件評估爲「真」的情況下才能「處理」片段內容。 此外,我的參考瀏覽器是MSIE6。我應該可能會得到另一份工作... – 2011-05-16 13:03:36

+0

MSIE具有極差的HTML表格渲染性能。我懷疑你的問題是否真的是由EL引起的。速度非常快。嘗試在其他瀏覽器中測試同一頁面,例如Firefox或Chrome - 僅供您參考。 – BalusC 2011-05-16 13:05:22

+0

我已澄清我的問題。 – 2011-05-16 14:23:23