[ http://jira.jboss.com/jira/browse/RF-3569?page=comments#action_12415509 ] martin bischoff commented on RF-3569: -------------------------------------
over the last days i adapted the src of the tree and changed the html structure from nested tables to ul-li constructs with a view to implement a relative complex styleguide. as a result of this, the cpu time allocation measured by jprofiler changed. here is a small comparision, maybe it helps you. modified tree - ul org.ajax4jsf.webapp.tidy.tidyparser.parsehtmlbytidy 86%: |-org.ajax4jsf.org.wc3.tidy.tidy.parsedom 31% |-org.ajax4jsf.org.wc3.tidy.tidy.pprint 23.5% |-org.wc3.dom.nodelist.getlength 20% |-org.wc3.dom.item 10% org.ajax4jsf.application.ajaxviewhandler.renderview 7.8% orgiginal tree - table org.ajax4jsf.webapp.tidy.tidyparser.parsehtmlbytidy 90%: |-org.ajax4jsf.org.wc3.tidy.tidy.parsedom 45% |-org.ajax4jsf.org.wc3.tidy.tidy.pprint 34.5% |-org.wc3.dom.nodelist.getlength 6.8% |-org.wc3.dom.item 3.6% org.ajax4jsf.application.ajaxviewhandler.renderview 7.6% > <rich:tree> possible performance issue > --------------------------------------- > > Key: RF-3569 > URL: http://jira.jboss.com/jira/browse/RF-3569 > Project: RichFaces > Issue Type: Quality Risk > Affects Versions: 3.2.0 > Reporter: martin bischoff > Assigned To: Nick Belaevski > Fix For: 3.2.2 > > > i've got an quite simple tree with "just" 50 elements �¡ 200 childs -> > 10.000 nodes > every node gots: > - some little text > - image for a checkbox via h:graphicImage > - a4j:support for listenersupport at the image > expanding/collapsing nodes and checking the checkboxes takes a lot of time... > jprofiler tells me that most of the time is spend by domparsing. i dont know > if i handle the tree as intended. here is some code: > JSP > [code] > <%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%> > <%@ taglib uri="http://richfaces.org/rich" prefix="rich"%> > <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%> > <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%> > <html> > <head> > <title>tree</title> > </head> > <body> > <f:view> > <h:form> > <a4j:loadStyle src="/res/button.css" /> > <a4j:loadStyle src="/res/tree/style.css" /> > <a4j:commandButton id="show_me" value="show childs" > styleClass="normalButton"> > <a4j:ajaxListener > type="controller.listener.ListenerBean" /> > </a4j:commandButton> > <h:panelGrid columns="2"> > <h:outputLabel> > <h:outputText value="infinite Tree extended"></h:outputText> > <rich:tree componentState="#{treeBean.treeState}" > id="infinite_Tree_expanded" style="width:300px" switchType="ajax" > stateAdvisor="#{treeDemoStateAdvisor}"> > > <rich:recursiveTreeNodesAdaptor roots="#{treeBean.rootNodes}" > var="item" nodes="#{item.children}"> > <rich:treeNode > nodeSelectListener="#{treeBean.processSelection}"> > <h:graphicImage value="/res/tree/chkb_#{item.state}.png"> > <a4j:support event="onclick" > reRender="infinite_Tree_expanded" actionListener="#{item.actionListener}"/> > </h:graphicImage> > <h:outputText value="#{item.value} - #{item.state}"/> > </rich:treeNode> > </rich:recursiveTreeNodesAdaptor> > > </rich:tree> > </h:outputLabel> > </h:panelGrid> > </h:form> > </f:view> > </body> > </html>[/code] > TreeBean: > [code]package my_tree; > import java.io.IOException; > import java.io.InputStream; > import java.util.Properties; > import javax.faces.FacesException; > import javax.faces.context.ExternalContext; > import javax.faces.context.FacesContext; > import javax.faces.event.AbortProcessingException; > import org.richfaces.component.state.TreeState; > import org.richfaces.event.NodeSelectedEvent; > public class TreeBean { > private TreeNode rootNode = null; > private TreeNode[] rootNodes = null; > private TreeState treeState; > private static final String DATA_PATH = > "/res/tree/simple-tree-data.properties"; > public TreeNode getRootNode() { > if (rootNode == null) { > loadTree(); > } > return rootNode; > } > public void setRootNode(TreeNode rootNode) { > this.rootNode = rootNode; > } > public TreeNode[] getRootNodes() { > if (rootNodes == null) { > rootNodes = this.getRootNode().getChildren(); > } > return rootNodes; > } > public void setRootNodes(TreeNode[] rootNodes) { > this.rootNodes = rootNodes; > } > public TreeState getTreeState() { > return treeState; > } > public void setTreeState(TreeState treeState) { > this.treeState = treeState; > } > private void addNodes(String path, TreeNode node, Properties > properties) { > boolean end = false; > int counter = 1; > while (!end) { > String key = path != null ? path + '.' + counter : > String > .valueOf(counter); > String value = properties.getProperty(key); > if (value != null) { > TreeNode newNode = new TreeNode(value); > newNode.setParent(node); > node.addNode(newNode); > addNodes(key, newNode, properties); > counter++; > } else { > end = true; > } > } > } > private void loadTree() { > System.out.println("TreeBean -> loadTree()"); > FacesContext facesContext = FacesContext.getCurrentInstance(); > ExternalContext externalContext = > facesContext.getExternalContext(); > InputStream dataStream = > externalContext.getResourceAsStream(DATA_PATH); > try { > Properties properties = new Properties(); > properties.load(dataStream); > rootNode = new TreeNode("root"); > addNodes(null, rootNode, properties); > // manual tree extension > TreeNode dummy = new TreeNode("Sichtlinie"); > int count = 0; > for (int i = 1; i <= 50; i++) { > count++; > TreeNode node = new TreeNode("i" + i); > for (int j = 1; j <= 200; j++) { > count++; > if (count % 1000 == 0) { > System.out.println(count); > } > TreeNode child = new TreeNode("j" + j); > child.setParent(node); > node.addNode(child); > } > node.setParent(dummy); > dummy.addNode(node); > } > rootNode.addNode(dummy); > } catch (IOException e) { > e.printStackTrace(); > throw new FacesException(e.getMessage(), e); > } finally { > if (dataStream != null) { > try { > dataStream.close(); > } catch (IOException e) { > e.printStackTrace(); > externalContext.log(e.getMessage(), e); > } > } > } > } > public void processSelection(NodeSelectedEvent arg0) > throws AbortProcessingException { > System.out.println("SimpleTreeBean -> processSelection fired by > " > + arg0.getComponent().getId()); > }[/code] > TreeNode: > [code]package my_tree; > import javax.faces.event.ActionEvent; > import org.richfaces.model.TreeNodeImpl; > public class TreeNode{ > private String value; > private String state; > private TreeNode parent; > private TreeNode[] children; > > public TreeNode(String value) { > this.value = value; > this.state = ""; > } > public synchronized void addNode(TreeNode newChild) { > System.out.println("addNode("+newChild.getValue()+")"); > if (this.children == null) { > TreeNode[] merged = new TreeNode[1]; > merged[0] = newChild; > this.children = merged; > } else { > TreeNode[] merged = new TreeNode[this.children.length + > 1]; > int i; > for (i = 0; i < this.children.length; i++) { > merged[i] = this.children[i]; > } > merged[merged.length - 1] = newChild; > this.children = merged; > } > } > public synchronized void addNodes(TreeNode[] newChildren) { > System.out.println("addNodeS("+newChildren.length+")"); > TreeNode[] merged = new TreeNode[newChildren.length > + this.children.length]; > int i; > for (i = 0; i <= this.children.length; i++) { > merged[i] = this.children[i]; > } > for (int i2 = i; i2 <= newChildren.length + i; i2++) { > merged[i2] = newChildren[i2]; > } > this.children = merged; > } > public synchronized void removeNodes(TreeNode[] removeChildren) { > TreeNode[] splitted = new TreeNode[this.children.length > - removeChildren.length]; > int pos = 0; > for (int i = 0; i <= this.children.length; i++) { > boolean contains = false; > for (int j = 0; j <= removeChildren.length; j++) { > if (this.children[i] == removeChildren[j]) { > contains = true; > } > } > if (contains == false) { > splitted[pos] = this.children[i]; > pos++; > } > } > } > public String checkSibling(){ > //System.out.println("checkSibling() of "+this.value); > if(this.children!=null){ > String state = null; > int checked = 0; > int sub = 0; > int i; > TreeNode[] siblings = this.children; > for (i = 0; i < siblings.length; i++) { > > TreeNode treeNode = siblings[i]; > //System.out.println("\t"+treeNode.getValue()+" > - "+treeNode.getState()); > if(!treeNode.getState().equals("")){ > > if(treeNode.getState().equals("checked")){ > checked++; > } else > if(treeNode.getState().equals("sub")){ > sub++; > } > } > > } > > if(checked == i){ > state = "checked"; > } else if(sub > 0 || checked > 0) { > state = "sub"; > } else { > state = ""; > } > //System.out.println("siblings: "+i+" (checked: > "+checked+" sub: "+sub+") -> "+state); > return state; > } else { > return ""; > } > } > > public void setChildsChecked(TreeNode node){ > //System.out.println("TreeNode -> setChildsChecked of > "+node.getValue()); > if(node.getChildren()!=null){ > TreeNode[] children = node.getChildren(); > for (int i = 0; i < children.length; i++) { > TreeNode treeNode = children[i]; > treeNode.setState("checked"); > setChildsChecked(treeNode); > } > } > } > > public void setChildsUnchecked(TreeNode node){ > //System.out.println("TreeNode -> setChildsUnchecked of > "+node.getValue()); > if(node.getChildren()!=null){ > TreeNode[] children = node.getChildren(); > for (int i = 0; i < children.length; i++) { > TreeNode treeNode = children[i]; > treeNode.setState(""); > setChildsUnchecked(treeNode); > } > } > } > public void setParentsState(TreeNode node){ > System.out.println("TreeNode -> setParentsState of > "+node.getValue()); > node.setState(node.checkSibling()); > if(node.getParent()!=null){ > setParentsState(node.getParent()); > } > } > > public void actionListener(ActionEvent ae){ > //System.out.println("TreeNode -> nodeListener fired by > "+ae.getComponent().getId()); > if(this.state == "checked"){ > this.state = ""; > setChildsUnchecked(this); > } else { > this.state = "checked"; > setChildsChecked(this); > } > if(this.parent!=null){ > setParentsState(this.parent); > } > > } > > public String getValue() { > return value; > } > public void setValue(String value) { > this.value = value; > } > public TreeNode[] getChildren() { > return children; > } > public void setChildren(TreeNode[] children) { > this.children = children; > } > > > public TreeNode getParent() { > if(parent==null){ > return null; > } else { > return parent; > } > } > public void setParent(TreeNode parent) { > this.parent = parent; > } > public String getState() { > return state; > } > public void setState(String state) { > this.state = state; > } > } > [/code] -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://jira.jboss.com/jira/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira _______________________________________________ richfaces-issues mailing list [email protected] https://lists.jboss.org/mailman/listinfo/richfaces-issues
