Tuesday, August 21, 2012

Increase your JSF application performance (Part 1 - Environment & Configuration)

  • Always use the newest MyFaces version (As you can read here: Blog Entry)
  • If you just need a plain servlet container, use Tomcat instead of Jetty
  • Use JUEL as EL implementation 
    • Add the newest JUEL API + implementation as depedency
    • Configure MyFaces to use JUEL:
    • <context-param>
              <param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
              <param-value>de.odysseus.el.ExpressionFactoryImpl</param-value>
      </context-param>
  • Increase expression cache in JUEL
    • Create src/main/resources/el.properties
    • Add property javax.el.cacheSize with a custom size. The default size is 1000. In my application i use a size of 3000.
  • If you use CDI, consider to use OpenWebBeans as implementation and configure this in your web.xml:
  • <context-param>
        <param-name>org.apache.myfaces.EL_RESOLVER_COMPARATOR</param-name>
        <param-value>org.apache.myfaces.el.unified.OpenWebBeansELResolverComparator</param-value>
    </context-param>
  • Enable MyFaces EL caching as described in MyFaces Wiki
  • Disable JSP support in MyFaces:
  • <context-param>
        <param-name>org.apache.myfaces.SUPPORT_JSP_AND_FACES_EL</param-name>
        <param-value>false</param-value>
    </context-param>
  • Other params to increase performance:
  • <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Production</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
        <param-value>-1</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.CHECK_ID_PRODUCTION_MODE</param-name>
        <param-value>false</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.VIEW_UNIQUE_IDS_CACHE_ENABLED</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.SAVE_STATE_WITH_VISIT_TREE_ON_PSS</param-name>
        <param-value>false</param-value>
    </context-param>
    
  • Configure state management as described in MyFaces Wiki
  • Use a custom ServletFilter to set the correct expires/cache headers of your resources (images, stylesheets, javascripts)
  • Compress and optimize your Javascripts in your build process. If you use maven, try primefaces-extensions' closure compiler maven plugin

11 comments:

  1. Thomas, thanks for this blog. I recognized it while reading one of your posts on PrimeFaces Core forum. I have taken most of your advice when it comes to JSF/Performance, I've already migrated to MyFaces Core, JUEL, I have added myfaces context-parameters in web.xml for performance reasons, I have read up on OpenWebBeans in last 12 hours, stayed up all night last night 'trying' to migrate from Glassfish 3.1.2.2 to Apache Tomcat 7.0.32, since I wanted to use PrimeFaces Push (atmosphere/websocket), but decided to postpone (for the 4th or 5th time after failure) using PrimeFaces Push with Glassfish 3.1.2.2, AND I decided to start migrating my app to CDI, initially the RI (weld), but OpenWebBeans (CDI) is in my sights. Reading about it now in Java EE 6 tutorial, and I think Ronald (in PrimeFaces Core forum) recommended someone else's blogs as well for using/coding CDI.

    ReplyDelete
    Replies
    1. UPDATE: As you may already know, Thomas, some time within the last month, I completed migration from Glassfish 3.1.2.2 and JSF-managed-beans to TomEE1.5.1+ and CDI-managed-beans, and the web app is running well in production, on 6-to-10-year old hardware and software (Windows Server 2003 32-bit 4GB RAM). So, I'm using OpenWebBeans, and myself and the endusers are loving the web app.

      So, thank you thank you thank you Thomas for any/all advice that you have offered!

      Delete
  2. Thomas,

    Of course, I am revisiting this, because the only outstanding thing I left undone was the following:

    Increase expression cache in JUEL
    Create src/main/resources/el.properties
    Add property javax.el.cacheSize with a custom size. The default size is 1000. In my application i use a size of 3000.

    1. Can you update this blog and include code-tagged example of el.properties file
    2. Also, I had to re-read JUEL documentation and learned that I can place el.properties anywhere on my classpath; i didn't understand what you meant by src/main/resources/..., as that folder path does not exist in my project (using netbeans).

    ReplyDelete
  3. Whats the problem? just add the property file with javax.el.cacheSize as key and the amount as value.

    src/main/resources will be moved to WEB-INF/classes in the WAR file.

    ReplyDelete
    Replies
    1. Okay. I had to refer to a properties file I saw in glassfish install folder that still remains on my dev server, and then I created the el.properties file and deployed it to production and tested it, but I'm not sure how to verify (via JMX) that javax.el.cacheSize is set. I'm multi-tasking a bit right now (improving performance of a SQL query).

      Delete
  4. Thanks for such social platform which give us variety of idea to explore ourself technically .This exposure give benefits to everyone to fit or to survive in global market which is very essential in the global era.
    Time Attendance Software In Pune

    ReplyDelete
  5. I have clashing between javax.el version : cannot merge imports of package 'javax.el' from sources 'Import-Library 'org.apache.myfaces' version '2.1.7'(null), Import-Library 'org.springframework.spring' version '3.1.3.RELEASE'(null), Import-Bundle 'javax.el' version '2.2.0.v201108011116', Import-Bundle 'de.odysseus.juel-api' version '2.2.6'' because of conflicting values 'de.odysseus.juel-api', 'javax.el' of attribute 'bundle-symbolic-name'. Tried to use juel-spi but how to add the bundle in the manifest when you don't have a symbolic name for juel-spi?

    ReplyDelete
  6. Hi Thomas,
    I found this interesting article while searching for a way to improve my web application performances and I was trying to follow your advices.
    I'm struggling to make this implementation work, and also with a new project I'm finding some difficulties.
    I'll be very grateful if you could help me or post an empty test project with the settings above that I can use as a base for some experimentation. Thank you in advance :)

    ReplyDelete
  7. Hi Thomas, if I'm using PF 4 with JSF 2.2. MyFaces still haven't 2.2 so only can to use mojarra, any tips for Mojarra

    ReplyDelete
  8. Setting org.apache.myfaces.SUPPORT_JSP_AND_FACES_EL to false my webapps stops working, even adding the listener mentioned (tested with MyFaces 2.2.1):
    HTTP Status 500 - No Factories configured for this Application. This happens if the faces-initialization does not work at all - make sure that you properly include all configuration settings necessary for a basic faces application and that all the necessary libs are included. Also check the logging output of your web application and your container for any exceptions!

    ReplyDelete