Hi Unfortunately we can't cache facelets generated unique ids into ComponentTagHandlerDelegate because a tag handler can be used in many views because a view is the result of execute many "facelet compositions".
In facelets there are two "hierarchical counters", one for MARK_CREATED (FaceletContext.generateUniqueId) and the other for component unique ids (FaceletCompositionContext.generateUniqueComponentId). In theory if the view is "static", which means it generates the same component tree each time, the list of generated ids will be the same. What we can do is create a per-view cache, holding an ordered list with the generated ids. In theory, when a dynamic part of a tree is about to begin, a new level is started calling FaceletCompositionContext.startComponentUniqueIdSection(), which increase the level calling SectionUniqueIdCounter.startUniqueIdSection() for both counters. So we could add some logic into SectionUniqueIdCounter to store the values of the counter on the base level and reuse it per view. It is not going to be an easy trick but it seems reasonable, because it will save a bunch of memory. About @ResourceDependency annotations: The current code in RequestViewContext check if the annotation was processed on the same view, which means if the resource has been already added. That code is ok. Note there is another cache that checks if the class has @ResourceDependency annotations, to prevent scan it, but what we don't have is one cache to store the classes that does not have any @ResourceDependency and prevent any scanning at all. Which is more expensive? a get() over a ConcurrentHashMap or a call to inspectedClass.getAnnotation()? Only if the first is cheaper, the cache has sense. Finally, I don't think we can do anything for clientId, because its generation is more tied to UIComponentBase internals. If an UIData or UIRepeat or any other iteration component is used, clientId changes per row, and is reset using setId() call. I think we can pass the clientId through component attribute map, using some special attribute name, but it doesn't sound good to me. After all, clientId calculation is responsibility of UIComponent and it could be changed on the related Renderer. regards, Leonardo Uribe 2012/2/20 Martin Koci <[email protected]>: > Same situation for clientId: in "stable" component tree is clientId > always the same (state saving depends on it) > > unfortunately has UIComponent no method setClientId. But we can try set > it via reflexion and compare if it brings an improvement or not. > Currently getClientId() uses lazy init and involves: > > findParentNamingContainer > namingContainer.getContainerClientId > stringBuilder appends > renderer.convertClientId > > > > Martin Koci píše v Pá 17. 02. 2012 v 18:56 +0100: >> Hi, >> >> in situation, where no build-time tags (c:if, co:foreach, ...) and no >> ui:include src="#{}" are used (and no direct component.getChildren() >> manipulation of course), builds VDL.buildView every time the same >> component structure (same graph). >> >> In this case compute myfaces some informations again and again but every >> time with same results. For example, creating of unique ids is very >> expensive: >> >> FaceletContext.generateUniqueId >> FaceletCompositionContext.generateUniqueComponentId >> UniqueIdVendor.createUniqueId >> >> in ComponentTagHandlerDelegate.apply(FaceletContext, UIComponent) >> >> Can we cache this ids at ComponentTagHandlerDelegate in production in >> case of view without build time modifications ? This is similar to [1]. >> >> Same situation with @ResourceDependency annotations: ApplicationImpl. >> _handleAttachedResourceDependencyAnnotations computes the same result >> with every request/response. >> >> Others ideas what can be cached? >> >> Regards, >> >> Kočičák >> >> >> [1] https://issues.apache.org/jira/browse/MYFACES-3160 >> >> >> >> >> >> >> >> > >
