thanks for your explaination and let me know more about clay details.
here, I borrow the clay template parser code to expand the my advice of
where and how merge verbatim component children.
because the template parsing usually runs only once and then generated meta
bean tree will be placed in cache for latter using, the performance of
template parsing isn't bottleneck and not important. so , parsing work is
inclined to hava an clear and extendable structured design. however, the
parsed results (that meta bean tree) are used over and over again, so,
optimizing results is meaningful.
the following code are from ClayTemplateParser.java, comments inserted
between lines.
protected ComponentBean generateElement(URL templateURL, String
templateName) throws IOException {
if (log.isInfoEnabled())
log.info(messages.getMessage("loading.template", new Object[]
{templateName}));
ComponentBean root = new ComponentBean();
root.setJsfid(templateName);
root.setComponentType("javax.faces.NamingContainer");
// generate the document
InputStream inputStream = null;
StringBuffer buffer = null;
try {
inputStream = templateURL.openStream();
buffer = loadTemplate(inputStream, templateName);
} finally {
if (inputStream != null)
inputStream.close();
}
List roots = new Parser().parse(buffer);
// here, the whole node tree already generated. To string
// "<html><head></head><body><h1>a</h1><body></html>", node
tree will be
// html
// -- head
// -- body
// -- -- h1
// -- -- -- a
Iterator ri = roots.iterator();
while (ri.hasNext()) {
Node node = (Node) ri.next();
Builder renderer = node.getBuilder();
ElementBean child = renderer.createElement(node);
// to first node "html", child's componentType will be
"javax.faces.HtmlOutputText"
root.addChild(child);
// then "html" elementbean added to ComponentBean root
if (renderer.isChildrenAllowed()) {
renderer.encode(node, child, child);
} else {
renderer.encode(node, child, root);
// because "HtmlOutputText" not isChildrenAllowed, In
"renderer.encode(node, child, root), elementbeans made from children "head"
and "body" nodes also directly be added to the root. for this analysis,
"h1" and "a" also directly be added to the root.
}
}
roots.clear();
roots = null;
buffer.setLength(0);
buffer = null;
ri = null;
// here , root has children elementbean list in which every
bean's type is "HtmlOutputText"
// root NamingContainer
// -- <html> HtmlOutputText
// -- <head> HtmlOutputText
// -- </head> HtmlOutputText
// -- <body> HtmlOutputText
// -- <h1> HtmlOutputText
// -- a HtmlOutputText
// -- </h1> HtmlOutputText
// -- </body> HtmlOutputText
// -- </html> HtmlOutputText
//verify there is not a duplicate component id within a naming
//container.
config.checkTree(root);
// here, you can merge those adjacent verbatim elements
config.optimizeTree(root);
// in optimizeTree, you can traverse elementbean tree, and
iterate children treeset of every element.
// while meeting continuous HtmlOutputText and it's value is not
valuebinding reference, you can merge them into one
// HtmlOutputText. Further, in fact , JSF EL can evaluate value
binding string like " abcd#{bean.value}efg#{bean2.value2}hi",
// so, you probably can merge more verbatim elementbean into
one.
return root;
}
From: [EMAIL PROTECTED] (Gary VanMatre)
Reply-To: "Struts Developers List" <dev@struts.apache.org>
To: "Struts Developers List" <dev@struts.apache.org>
Subject: Re: [shale] some improvement proposal for performance
Date: Thu, 25 May 2006 15:35:13 +0000
>From: 林 明 <[EMAIL PROTECTED]>
>
> thanks much for comments.
>
> Now give some explaination from me.
> To jsf component tree iterating, I only give a guess if we use treemap
but
> not arraylist to store children components. The disadvantage of that is
> necessary space of component tree struture will be great larger. But we
can
> direct find corresponded component to the request data. for example if
we
> find "id0:id8:subview:clay:id19", we can quickly use treemap to find it
> like viewroot.children("id0").children("id8").children("subview")...
and so
> on. Because except restoreview and render phase or broadcast event of
other
> phases, actually we only need get few components from tree for
> applyrequest,validating or updatemodel. Current, myfaces uses visitor
> pattern to traverse the whole tree. In our project , some page may have
> tens of form inputs components, but have many other layout components ,
> component instances easily come up hundreds. so, if we only process
> components needed, jsf will not burden with not good reputation of
> performance.
>
This is really more of a JSF runtime issue. Shale uses an existing
runtime.
From what I understand, JSF 1.2 will allow you to do partial handling of
the component tree
(http://weblogs.java.net/blog/jhook/archive/2006/02/new_feature_for.html).
Clay creates a metadata layer that is used to create the component tree.
Clay
has a custom view handler for full html and xml views (defining the page
entry
point) that just adds the Clay component under the view root. The
component
handles creating the subtree. The Clay component is a naming container
too.
The metadata layer is defined by a graph of simple beans that is created
from
an XML or HTML source. Both the HTML parser and the digested XML create
the same type of beans. The Clay component only has to know about one
type
of metadata to build the component tree.
So, if you are using Clay, besides having the overhead of large component
trees,
you will also have the overhead of the POJO's that define the tree.
When the view is restored and then rendered, and if you are using client
side state
saving, the verbatim components must be recreated from the metadata since
they
are not pushed to the client. The have to be inserted back into the tree.
The
CreateComponentCommand looks for an existing component by id before
creating a new one. This search is done from the parent and not the
view root - parent.findComponent(id). So the sequential search is only
for the
children of the active parent.
If you are trying to get the best performance out of JSF, you might want
to
just create the component tree from java code and not even use templating.
You could create a view handler that maps the view id to a builder. This
would
be more like servlet programming but the only thing you would have to
handle is
building the component tree. This would give you the best performance.
> To merge adjacent verbatim components, because those components usually
> stand in the same
> children list and already not in hierarchical node tree after you
> processing and creating ComponentBean Tree, you can at this point to
merge
> them.
>
Only looking at merging children would be simpler than trying to
reorganize the tree.
It will require processing the entire (metadata) tree again which may not
be any faster
than creating some extra components.
Gary
> regards.
>
> aftermath :-)
>
>
>
_________________________________________________________________
与联机的朋友进行交流,请使用 MSN Messenger: http://messenger.msn.com/cn
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]