2014-10-22 30 views
1

我正在處理Primefaces社區(5.1)的最新版本中的一個問題。將它與JSF 2.1.29和+1000元素結合使用會在使用Google Chrome 38瀏覽器時帶來可怕的性能問題,無論是視圖加載和元素轉移。我擔心這是Chrome的Javascript引擎中的一個問題。在這裏,您已經有了一個非常基本的用例:在Chrome瀏覽器中有大量元素的PickList變慢了

@ManagedBean 
@ViewScoped 
public class PickListTestBean implements Serializable { 

    private DualListModel<String> values; 

    public PickListTestBean() { 
     List<String> source = new ArrayList<String>(); 
     List<String> target = new ArrayList<String>(); 
     for (int i = 0; i < 1000; i++) { 
      source.add("value" + i); 
     } 
     values = new DualListModel<String>(source, target); 
    } 

    public DualListModel<String> getValues() { 
     return values; 
    } 

    public void setValues(DualListModel<String> values) { 
     this.values = values; 
    } 

} 

和視圖:

<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:h="http://xmlns.jcp.org/jsf/html" 
    xmlns:f="http://xmlns.jcp.org/jsf/core" 
    xmlns:p="http://primefaces.org/ui" 
    xmlns:ui="http://java.sun.com/jsf/facelets"> 
    <h:head /> 
    <h:body> 
     <h:form> 
      <p:pickList value="#{pickListTestBean.values}" var="val" 
       effect="none" itemValue="#{val}" itemLabel="#{val}" 
       showSourceFilter="true" showTargetFilter="true"> 
       <p:column> 
        #{val} 
       </p:column> 
      </p:pickList> 
     </h:form> 
    </h:body> 
</html> 

這是正常的FF和IE瀏覽器最新版本的工作...

回答

1

似乎是一個Primefaces問題,我打開了一張票,但他們說他們不打算修復它,因爲組件的元素太多(這是真的)。但是,有一種方法可以提高效率。對項目產生循環直接通過DOM追加的HTML內容的功能:

generateItems: function(list, input) { 
    list.children('.ui-picklist-item').each(function() { 
     var item = $(this), 
     itemValue = PrimeFaces.escapeHTML(item.attr('data-item-value')), 
     itemLabel = item.attr('data-item-label'), 
     escapedItemLabel = (itemLabel) ? PrimeFaces.escapeHTML(itemLabel) : ''; 

     input.append('<option value="' + itemValue + '" selected="selected">' + escapedItemLabel + '</option>'); 
    }); 
} 

重寫爲PickListgenerateItems功能顯着提高演出]:

<script> 
    PrimeFaces.widget.PickList.prototype.generateItems = function(b, a) { 
     var output = ''; 
     b.children(".ui-picklist-item").each(function() { 
      var e = $(this), 
      f = PrimeFaces.escapeHTML(e.attr("data-item-value")), 
      d = e.attr("data-item-label"), 
      c = (d) ? PrimeFaces.escapeHTML(d) : ""; 
      output += '<option value="' + f + '" selected="selected">' + c + "</option>"; 
     }) 
     a.append(output) 
    } 
</script> 
0

略有改動上面的回答。如果你只在目標選擇感興趣,並想用一個大的輸入源,你可能需要使用以下內容:

PrimeFaces.widget.PickList.prototype.generateItems = function(b, a) { 
    var output = ''; 
    if(b === this.targetList) { 
     b.children(".ui-picklist-item").each(function() { 
      var e = $(this), 
      f = PrimeFaces.escapeHTML(e.attr("data-item-value")), 
      d = e.attr("data-item-label"), 
      c = (d) ? PrimeFaces.escapeHTML(d) : ""; 
      output += ('<option value="' + f + '" selected="selected">' + c + '</option>'); 
     }); 
    } 
    a.append(output); 
}; 

這將確保處理僅在(小)目標進行名單。因此,DualListModel將返回源中的零個元素,同時將選擇作爲目標返回。

相關問題