4

I don't know whether it is true or not but from what I've read, I believe, JSF EL & xhtml pages are not pre-compiled & just used when needed but instead they are parsed, evaluated, compiled each time the view is built.

I fail to understand why this is done so! Why not just parse & compile it just once, ok atleast partially , rendering of some components may depend on a dynamically fetched variable so they may be rendered later but why delay that for all the components on page? Whatever maximum could be pre-compiled & made ready to use, why not do it just when the application is deployed? Wont this improve rendering time of the pages ?

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
Rajat Gupta
  • 23,343
  • 56
  • 165
  • 281

1 Answers1

9

Facelets is actually capable of "precompiling". You can control the Facelets refresh period with the context parameter javax.faces.FACELETS_REFRESH_PERIOD. You can set it to -1 in order to tell JSF to never re-compile/re-parse the Facelets files and actually hold the entire SAX-compiled/parsed XML tree (based on the XHTML compositions) in cache:

<context-param>
    <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
    <param-value>-1</param-value>
</context-param>

Don't use this setting during development though, or you must restart the whole server on every edit of a Facelets file. Mojarra has a default setting of 2 (meaning, cache will be refreshed every 2 seconds). MyFaces has a default setting of -1 when javax.faces.PROJECT_STAGE is not set to Development.

You can if necessary control the Facelets cache by providing a custom FaceletsCacheFactory and FaceletsCache. Note that this is only available since JSF 2.1 and thus you'd need to redeclare your faces-config.xml conform JSF 2.1 in order to get <facelet-cache-factory> configuration setting to work.

To get a step further, the views which are built based on the XML tree (so, the entire UIViewRoot) could theoretically also be pooled. MyFaces is currently already making some effort in order to achieve this, see also issue 3664. My fellow Arjan Tijms is in his spare time also looking at it for Mojarra.

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • 1
    Thanks, I was waiting for your answer! So the parsing/compilation is not done on per request basis, it is cached *for all requests* for some configurable time, right? (Actually I believed it was done each time when new requests to render a view came up, as some recommend to choose a better EL parser implementation like JUEL etc for improved performance) & why do we even need a small refresh time of 2 seconds when project is not in dev stage but instead a longer time could be used, no? – Rajat Gupta Jul 27 '13 at 04:24
  • That's correct. During production whereby Facelets files are never changed during runtime, it would indeed make completely sense to set it to -1. – BalusC Jul 27 '13 at 12:19
  • Thanks, just a small correction that Myfaces default value for this param is -1. (See http://myfaces.apache.org/core20/myfaces-impl/webconfig.html#facelets_REFRESH_PERIOD). Also view pooling is a much wanted feature & would give a great performance boost. – Rajat Gupta Jul 27 '13 at 14:40
  • Whoops, I mixed it with `org.apache.myfaces.CONFIG_REFRESH_PERIOD`. Fixed. – BalusC Jul 27 '13 at 14:45
  • so now I think there is no need to use any custom EL implementations like JUEL etc just for any performance concerns ?! – Rajat Gupta Jul 27 '13 at 14:45
  • 1
    EL is not evaluated during compiling/parsing. It's evaluated during view building and view rendering. So to improve render time performance it may be worth the effort to benchmark the EL performance and try different implementations. I've indeed read that using JUEL made quite a difference. Haven't tried it myself yet. Arjan T may look into it. – BalusC Jul 27 '13 at 14:46
  • 1
    Ouch, commenting on an old answer asking about progress. Never thought I'd do that, but here I go: _"My fellow Arjan Tijms is in his spare time also looking at it for Mojarra."_ Any progress? Code to try? I have a very complex ajax intensive form and think this might help a lot – Kukeltje Nov 10 '15 at 20:42
  • 1
    @Kukeltje: No, he stopped once he discovered that Rudi Simic took a very similar path and was more advanced: http://blog.industrieit.com/2011/11/14/stateless-jsf-high-performance-zero-per-request-memory-overhead/ This is as of now thus partially taken over in MyFaces since 2.2.0. He blogged about a VDL with pooling idea http://jdevelopment.nl/authoring-jsf-pages-pure-java/. It's however a Java VDL not XHTML VDL, but the pooling idea could be ripped off from here https://github.com/arjantijms/javavdl/blob/master/src/javavdl/impl/JavaViewDeclarationLanguage.java#L60 – BalusC Nov 10 '15 at 21:08
  • @BalusC: Does your words **re-compile/re-parse** mean one & the same thing in context to Facelets? (I mean parsing & compilation are different when it comes to JavaScript.) – Farhan Shirgill Ansari Jul 24 '16 at 09:15
  • 1
    @Shirgill: the question asks for "compile", but the actual behavior is "parse". There's no means of compilation here (changing from one language to another language e.g. bytecode). The word "precompiling" is hence placed in quotes. – BalusC Jul 24 '16 at 09:40