在Google Chrome中,包含大量元素的PickList会变慢

时间:2014-10-22 06:55:29

标签: google-chrome jsf primefaces

我正在处理上一版Primefaces社区(5.1)中的一个问题。在使用Google Chrome 38浏览器时,无论是在视图加载还是元素传输中,将它与JSF 2.1.29和+1000元素一起使用都会带来严重的性能问题。我担心Chrome的Javascript引擎会出现问题。在这里你有一个非常基本的用例:

@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最新版本中正常工作......

2 个答案:

答案 0 :(得分: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>');
    });
}

覆盖generateItems的{​​{1}}函数可显着提高性能:

PickList

答案 1 :(得分: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将在源中返回零元素,同时将选择返回为目标。