ICEfaces
  1. ICEfaces
  2. ICE-8388

Improve resource caching with new session

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.1.0.RC1
    • Fix Version/s: 3.3
    • Component/s: ACE-Components, Bridge
    • Labels:
      None
    • Environment:
      ICEfaces

      Description

      CSS and JavaScript caching should be investigated and improved if necessary. JSF supports dynamic modification of resources through EL which may interfere with caching, but resources could be structured to not require dynamic modification.

        Activity

        Hide
        Ted Goddard added a comment -

        The issue in the forum post is likely due to the ;jsessionid parameter in the resource URLs. To improve this case, it would be necessary to generate non-session-specific resources with simple URLs.

        Show
        Ted Goddard added a comment - The issue in the forum post is likely due to the ;jsessionid parameter in the resource URLs. To improve this case, it would be necessary to generate non-session-specific resources with simple URLs.
        Hide
        Mark Collette added a comment - - edited

        When a user first accesses a web application page, the application server will detect if the jsessionid cookie has been set, and will see that it is not. At this point, the application server does not know if cookies are even enabled on the browser, so it will try to set the jsessionid cookie, and as well, any URL that is passed in to JSF's ExternalContext's encodeActionURL(String) or encodeResourceURL(String) methods will have the jsessionid appended to them as a GET parameter. On the postback, the application server will detect that the jsessionid cookie is now set, if cookies are enabled, and cease appending them in the encodeActionURL, encodeResourceURL methods. This can cause many DOM differences to key parts of the page, like the head and form(s).

        When a URL has a GET parameter on it, especially one that is new and unique, browsers won't have had that resource cached, so they'll need to be downloaded. This means that the initial page load with a new session will require a full download of all resources that have the jsessionid parameters on them.

        Then, when the postback occurs, and the jsessionid GET parameters are no longer on the resource links, they are treated as different URLs then they just were. If the user has never used the application before and not previously done a postback, then they will now download all of the resources for the second time of this session. This is the worst case scenario, and every new user of an application experiences it.

        Most of the resources used are not actually session scoped, they're application scoped, so a jsessionid GET parameter is unnecessary and undesirable. If we can stop it from being appended to those resources' URLs, that would solve all of these problems.

        Show
        Mark Collette added a comment - - edited When a user first accesses a web application page, the application server will detect if the jsessionid cookie has been set, and will see that it is not. At this point, the application server does not know if cookies are even enabled on the browser, so it will try to set the jsessionid cookie, and as well, any URL that is passed in to JSF's ExternalContext's encodeActionURL(String) or encodeResourceURL(String) methods will have the jsessionid appended to them as a GET parameter. On the postback, the application server will detect that the jsessionid cookie is now set, if cookies are enabled, and cease appending them in the encodeActionURL, encodeResourceURL methods. This can cause many DOM differences to key parts of the page, like the head and form(s). When a URL has a GET parameter on it, especially one that is new and unique, browsers won't have had that resource cached, so they'll need to be downloaded. This means that the initial page load with a new session will require a full download of all resources that have the jsessionid parameters on them. Then, when the postback occurs, and the jsessionid GET parameters are no longer on the resource links, they are treated as different URLs then they just were. If the user has never used the application before and not previously done a postback, then they will now download all of the resources for the second time of this session. This is the worst case scenario, and every new user of an application experiences it. Most of the resources used are not actually session scoped, they're application scoped, so a jsessionid GET parameter is unnecessary and undesirable. If we can stop it from being appended to those resources' URLs, that would solve all of these problems.
        Hide
        Ted Goddard added a comment -

        Note that this is not ICEfaces-specific, and is a common problem for all JSF and even many JSP applications.

        Show
        Ted Goddard added a comment - Note that this is not ICEfaces-specific, and is a common problem for all JSF and even many JSP applications.
        Hide
        Mark Collette added a comment -

        There are broader issues with jsessionid disappearing on postback, than just the resource caching, that perhaps we should take into consideration for solving this.

        1. Full form updates. The form's action attribute changes to omit the jsessionid, and we update the whole form, which can interfere with component state. For example, ICE-6697 fileEntry uploading, and ICE-7740 submitMonitor.

        2. Bookmarkability.ICE-8265.

        Some additional resolution ideas were:

        • When first loading a page with no session cookie or jsessionid in the url, then don't render the full page with all the jsesssionid links that will then disappear on the first postback. Instead do a temporary redirect to the same page, and immediately determine if there are cookies, and render the page accordingly. Take care to not infinite loop on temporary redirecting.
        • Either use generic attribute updating in the dom differencing, or if necessary, form action attribute updating, to avoid updating the whole form and contents.
        Show
        Mark Collette added a comment - There are broader issues with jsessionid disappearing on postback, than just the resource caching, that perhaps we should take into consideration for solving this. 1. Full form updates. The form's action attribute changes to omit the jsessionid, and we update the whole form, which can interfere with component state. For example, ICE-6697 fileEntry uploading, and ICE-7740 submitMonitor. 2. Bookmarkability. ICE-8265 . Some additional resolution ideas were: When first loading a page with no session cookie or jsessionid in the url, then don't render the full page with all the jsesssionid links that will then disappear on the first postback. Instead do a temporary redirect to the same page, and immediately determine if there are cookies, and render the page accordingly. Take care to not infinite loop on temporary redirecting. Either use generic attribute updating in the dom differencing, or if necessary, form action attribute updating, to avoid updating the whole form and contents.
        Hide
        Deryk Sinotte added a comment -

        I suspect that a viable workaround for many applications would be to simply turn the URL rewriting off. I'd hazard a guess that the vast majority of applications allow the use of cookies for this and that the jsessionid is simply a "backup" plan in case cookies aren't enabled. This would be done either in the app server's configuration or via a web.xml setting (which may only be part of the newer Java EE spec).

        http://docs.oracle.com/javaee/6/api/javax/servlet/SessionTrackingMode.html

        Handling the URL scenario may still be worthwhile to tackle, but for many, just turning it off would solve most problems.

        Show
        Deryk Sinotte added a comment - I suspect that a viable workaround for many applications would be to simply turn the URL rewriting off. I'd hazard a guess that the vast majority of applications allow the use of cookies for this and that the jsessionid is simply a "backup" plan in case cookies aren't enabled. This would be done either in the app server's configuration or via a web.xml setting (which may only be part of the newer Java EE spec). http://docs.oracle.com/javaee/6/api/javax/servlet/SessionTrackingMode.html Handling the URL scenario may still be worthwhile to tackle, but for many, just turning it off would solve most problems.
        Hide
        Ted Goddard added a comment -

        Tomcat allows tracking-mode to be configured, which might disable the initial use of ;jsessionid

        http://tomcat.apache.org/migration-7.html#Session_cookie_configuration

        Show
        Ted Goddard added a comment - Tomcat allows tracking-mode to be configured, which might disable the initial use of ;jsessionid http://tomcat.apache.org/migration-7.html#Session_cookie_configuration
        Hide
        Mircea Toma added a comment -

        Starting to investigate if the encoding of jsessionid URL parameter is really necessary since all JSF resources are served from the file system, which makes them application scoped.

        Show
        Mircea Toma added a comment - Starting to investigate if the encoding of jsessionid URL parameter is really necessary since all JSF resources are served from the file system, which makes them application scoped.
        Hide
        Mircea Toma added a comment -

        Modified ICEfaces core to not encode the jsessionid path parameter into URLs that point to JS or CSS resources. It was observed that since most of the resource are referenced in the html>head they are not reloaded, even when the mentioned modification was removed. This is caused by JSF's inability to update the head element.
        When org.icefaces.generateHeadUpdate feature is enabled then ICEfaces will generate a custom update for the head, but when this is processed on the client the bridge will discard the path parameters. Because of that the bridge won't reload these resources because it sees them as already being loaded.

        Show
        Mircea Toma added a comment - Modified ICEfaces core to not encode the jsessionid path parameter into URLs that point to JS or CSS resources. It was observed that since most of the resource are referenced in the html>head they are not reloaded, even when the mentioned modification was removed. This is caused by JSF's inability to update the head element. When org.icefaces.generateHeadUpdate feature is enabled then ICEfaces will generate a custom update for the head, but when this is processed on the client the bridge will discard the path parameters. Because of that the bridge won't reload these resources because it sees them as already being loaded.
        Hide
        Mircea Toma added a comment -

        Modified ICEFacesContextFactory to generate custom ExternalContext objects that override ExternalContext.encodeResourceURL behaviour. The modified method will avoid to encode the jsessionid path parameter when the URL contains the "javax.faces.resource" identifier or the mime type is of an image, audio, video, text/css or text/javascript files.

        Show
        Mircea Toma added a comment - Modified ICEFacesContextFactory to generate custom ExternalContext objects that override ExternalContext.encodeResourceURL behaviour. The modified method will avoid to encode the jsessionid path parameter when the URL contains the "javax.faces.resource" identifier or the mime type is of an image, audio, video, text/css or text/javascript files.

          People

          • Assignee:
            Mircea Toma
            Reporter:
            Ted Goddard
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: