I would like to ask you a question, which is related to another question I asked some times ago (without answer unfortunately :( )
Imagine that your project is divided into several web-apps. You also have many shared resources (JS, CSS, images). The idea is to avoid duplications in each web-app, as you will be forced to synchronize your changes among all the web-applications.
So it seems better to have these resources on a single place.
If I have a look on the Richfaces project, all their resources are managed by JSF.
For example, the <rich:calendar> component displays a little icon.
If we look the HTML code for this image, we see that the src attribute refers to a jsf link, not a .png directly:
<img src="/richfaces-demo/a4j/g/3_3_3.Finalorg.richfaces.renderkit.html.iconimages.CalendarIcon/DATB/eAH7cW0fw6znAA8XBA4_.jsf"
style="vertical-align: middle" id="j_id354:j_id355PopupButton" class="rich-calendar-button " alt="">
I see the following advantages of such approach:
Regarding my application, I will only need the first point, but it is really important to me (cf. my other related question on SO).
The main drawback of this solution is that the browser will not be able to cache the resources as they are considered as JSF requests. Also, each of these requests will have to go through the whole JSF lifecycle, which can be a performance issue if the number of resources in the current page is important...
Questions
Thanks.
Yes, it is definitely a good idea to put shared resources in a separate project which is to be included as a JAR in the main web applications. We however use a simple @WebServlet for this which serves the static resources straight from the classpath, along with cache and gzip support. We don't delegate this job to the JSF, we just utilize JSF resource management which in turn fully transparently calls the servlet by URL.
Allow to generate dynamic file (i.e. CSS or JS that only contain the required properties)
That's also doable by using a specific URL and then passing the filenames of the separate resources as query string. The static resource servlet will then do the nasty work of reading multiple resources into a single response.
Allow the inclusion of only the required resources (for ex. we will not load a CSS file if it is not required by a component on the page).
That's to be done by @ResourceDependency annotation. E.g.
@ResourceDependency(library="css", name="specific.css")
public class CustomComponentWithCSS extends UIComponentBase {
// ...
}
We use a modified version of this FileServlet which is altered to get the resource from the classpath instead of from local disk file system. Also, range support is removed (since RandomAccessFile can't directly operate on classpath resources). Further we have added a check if the current stage is development or not and if not, then serve a minified version of CSS/JS instead which is put in a different path.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With