jsr372-experts@javaserverfaces-spec-public.java.net

[jsr372-experts] Re: [JAVASERVERFACES_SPEC_PUBLIC-1404] Add UIViewRoot#getRenderedComponentResources()

From: Bauke Scholtz <balusc_at_gmail.com>
Date: Thu, 23 Jun 2016 17:05:06 +0000

Another way would be passing resource path to JS and have it check if it's
already in DOM and if not, then dynamically create script element.

Cheers, B

On Thu, Jun 23, 2016, 16:20 Leonardo Uribe <leonardo.uribe_at_irian.at> wrote:

> Hi
>
> I have seen this issue opened:
>
> https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1404
> Add UIViewRoot#getRenderedComponentResources()
>
> I would like to contribute with some thoughts about this issue that could
> help to solve
> some issues we already have in this part, and that could be fixed on the
> way.
>
> In MyFaces as you already know there is also a map that is used to
> indicate when
> a resource has been already rendered in the response.
>
> This solution is far from being perfect. It just check if a resource has
> been rendered
> more that once on the current request but:
>
> - On each request this map is filled over and over and over again. By
> performance
> reasons, this map is not saved on the state, but in fact each resource has
> one or
> many associated components that just point to each resource, so this
> information is
> in the tree structure, but there is no standard way to calculate it from
> the current
> view.
>
> - If you are building the whole view, you want this map to be empty before
> render the
> view, but on an ajax request things change, because in this case you
> assume there is
> already a view built on the client with the scripts, so you want this map
> already filled
> but before render the ajax fragment.
>
> If we remember the case "Dynamic resource loading in ajax requests", if we
> don't solve
> this problem some scripts could be loaded over and over even if they have
> been already
> there by other components.
>
> So, this is a "transient" HashSet that should be cleared and filled when
> the view is fully
> built. But in an ajax request, we need something to rebuild the set before
> render the ajax
> fragments. We don't need to traverse the whole tree, because we know that
> all resource
> components that matters can be retrieved from
> UIViewRoot.getComponentResources(...)
> (look with target=head, body or form).
>
> I can imagine a custom component event to register the resources on the
> map and a
> @ListenerFor annotation of each renderer (h:outputScript and
> h:outputStylesheet). It is not
> necessary to traverse the whole component tree, just a small fragment of
> the tree, and
> it is necessary to give each component a way to register themselves on the
> map. Again,
> this requires some changes on the spec. The reason why the components must
> register
> themselves is there are the case where h:outputScript renders as a script
> block so the
> algorithm should skip those components and the only way to know that is
> ask to each
> component itself.
>
> regards,
>
> Leonardo Uribe
>