在使用JSF(java server face)的的组合框和列表框时(UISelectOne和UISelectMany的子类),当可选列表太多时,尤其是当value属性绑定到
一个Bean上时更慢,跟踪日志发现,在向客户端输出HTML时调用了很多次getValue方法,而value属性又绑定了BEAN上,又会调用BEAN的方法,
如果在BEAN的方法中做了些处理,会带来很大的性能开销。
通过分析MenuRender类发现,多次调用getValue是完全没必要的,可以做到只调用一次,从而大大提高系能,具体修改如下:
输出组合框的option是调有renderOptions方法来实现,而renderOptions方法中又在循环中调用renderOption方法,renderOption方法是通过
调用getCurrentSelectedValues来取当前选择的值的,在getCurrentSelectedValues中最终调用的组合框组件类的getValue方法。要优化首先
应避免在循环中调用getCurrentSelectedValues方法,通过在循环前面调用一次getCurrentSelectedValues,把这个值放在一个变量中,修改
renderOptions和renderOption方法,把保存的值传过去[增加一个参数],这样避免了在renderOption方法中多次调用getCurrentSelectedValues
了,从而达到优化性能的目的。具体修改见下:
//MenuRenderer.java
renderSelect方法
....................
Object currentSelectedValue=this.getCurrentSelectedValues(context,component);
// Now, render the "options" portion...
renderOptions(context, component,currentSelectedValue);
writer.endElement("select");
void renderOptions(FacesContext context, UIComponent component,Object currentSelectedValue) throws IOException {
...........
while (items.hasNext()) {
..............
for (int i = 0; i < itemsArray.length; ++i) {
renderOption(context, component, itemsArray[i],currentSelectedValue);
}
writer.endElement("optgroup");
} else {
renderOption(context, component, curItem,currentSelectedValue);
}
}
.............
}
protected void renderOption(FacesContext context, UIComponent component, SelectItem curItem,Object currentSelectedValue) throws IOException {
ResponseWriter writer = context.getResponseWriter();
Util.doAssert(writer != null);
writer.writeText("/t", null);
writer.startElement("option", component);
String valueString = getFormattedValue(context, component, curItem.getValue());
writer.writeAttribute("value", valueString, "value");
Object submittedValues[] = getSubmittedSelectedValues(context, component);
boolean isSelected;
if (submittedValues != null) {
isSelected = isSelected(valueString, submittedValues);
} else {
Object selectedValues =currentSelectedValue; //getCurrentSelectedValues(context, component);
isSelected = isSelected(curItem.getValue(), selectedValues);
}
if (isSelected) {
writer.writeAttribute(getSelectedTextString(), Boolean.TRUE, null);
}
if (curItem.isDisabled()) {
writer.writeAttribute("disabled", "disabled", "disabled");
}
String labelClass = null;
Boolean disabledAttr = (Boolean) component.getAttributes().get("disabled");
boolean componentDisabled = false;
if (disabledAttr != null) {
if (disabledAttr.equals(Boolean.TRUE)) {
componentDisabled = true;
}
}
if (componentDisabled || curItem.isDisabled()) {
labelClass = (String) component.getAttributes().get("disabledClass");
} else {
labelClass = (String) component.getAttributes().get("enabledClass");
}
if (labelClass != null) {
writer.writeAttribute("class", labelClass, "labelClass");
}
writer.writeText(curItem.getLabel(), "label");
writer.endElement("option");
writer.writeText("/n", null);
}
// SelectManyCheckboxListRenderer类也需要类似修改