myfaces-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Leonardo Uribe <>
Subject Re: [core] performance: cache infos for views without build time modifications
Date Mon, 20 Feb 2012 22:51:16 GMT

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

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.


Leonardo Uribe

2012/2/20 Martin Koci <>:
> 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]

View raw message