34.Upgrades

Upgrades and Backward Compatibility

The upgrade from cookies to web-storage discussed below has now been implemented. However, while the latest versions of most popular browser all seem to support web-storage, the original cookie method will hopefully still work on older browser. The problem that prompted the upgrade was linked to the continued growth in the size of the website itself, such that the number of pages caused the 4-8kbyte cookie limited imposed by the host and many browsers to be exceeded. Any feedback on any observed problems would be welcomed.

1 Over the course of time, new features are introduced into the collective web standards, which ultimately find application in many websites. However, there are two distinct classes of problems connected with any functional upgrade of a website:

  • Browser Variance
  • Backward Compatibility

The first issue of 'browser variance' is caused by the functionality of a new feature being implemented in different ways in different browsers, while the second issue of 'backward compatibility' relates to the operation of any upgraded website, when viewed using an older browser, which does not support the new feature. By way of an example of the issues involved, the following discussion will consider a potential upgrade that is currently under consideration for this website in terms of the HTML5 functionality known as 'web storage' and its implications on the 5 browsers used to test this website:

  • Internet Explorer
  • Mozilla Firefox
  • Google Chrome
  • Apple Safari
  • Opera

The 5 browsers listed above account for 94.6% of the browser market, as per 2011, which is well above the 80/20 rule related to effort on return. However, before getting into the details associated with HTML5 web storage, it might be worth explaining what original functionality this feature might replace in the future. Originally, when this website was first developed, the tree and sitemap menus had no 'memory', so that when you switched to a new page, the open status of these menus was reset to its default state. So having taken the trouble to open up the tree structure to find a specific topic, it was more than a little irritating for the tree structure to then immediately collapse back to its default state, when switching to the topic just found.

So what mechanisms, if any, were available to address this requirement?

In essence, the 'web' is based on requests and responses formatted into the HTTP protocol, which is a stateless protocol that does not require the server to retain any information or status about the client-user between successive requests. However, within the overall development of the web, the idea of a 'cookie' was proposed, as early as 1994, so that a website could send user-specific data to the client-side browser and for that browser to then return updated information back to the website server. This data could then be used for any number of applications, e.g.

  • General authentication
  • Identification of a previous user session
  • User preferences
  • Shopping cart contents

However, in the context of this website, it was recognised that a cookie could contain the open tree state associated with the tree and sitemap menus in both website1 and website2. This eventually led to the development of a number of Javascript functions, which supported 4 cookies:

  • Tree1Cookie -> 3950 bytes
  • Site1Cookie -> 3950 bytes
  • Tree2Cookie -> 232 bytes
  • Site2Cookie -> 232 bytes

The relevance of the cookie size is discussed below, although the Javascript functions will not be described in any detail as most of this information can already be found by searching the web with some appropriate key, e.g. javascript cookie code. So, by the time the code was developed, i.e. 2006, it all appeared to work without too many backward compatibility issues, as by this time, the cookie functionality was well established in most browsers. Therefore, in a degree of ignorance of some of the underlying issues, the cookie mechanism was deployed, tested and forgotten about, as the primary focus was on web content, not just web implementation.

Where did this ignorance lead?

Unfortunately, a problem appeared quite recently as the size of each website was expanded in terms of the number of pages. Originally, it was not realised that cookies are encoded into the HTTP protocol and then passed between web server and client-side browser. As outlined, this website created 4 cookies, as listed above, which then had to be transported within the HTTP protocol, which it turns out that most servers check for some overall size limit. The exact size depends on the company that is providing the web hosting service for your website, but will typically be between 4-8Kbytes. Clearly, the growth in the sizes of the website was bound to cause a problem sooner or later, as the size of the cookies reflected this growth.

But surely, the problem was detected before deploying to the live website?

Actually, it was not detected in testing, because being a client-side design, the websites can be run locally on any PC without a server. In this environment the checks on the total size of the HTTP request packages are either not performed or have some higher maximum than my actual web host server. So it came as a bit of a surprise, after uploading the websites to the server to discover a serious run-time error occurring, which manifested itself as a somewhat non-descript server error. However, after an exchange of problems reports with my web host provider, it seemed that my cookie mechanism was exceeding the HTTP packet size imposed by the server and that some other solution would be required.

Short-Term Solution

Before outlining the issues surrounding a potential implementation based on the HTML5 web storage approach, it is worth outlining the basic solution taken regarding the immediate and urgent problem with the cookie mechanism. The solution adopted was quite simple once it was realised that the server error was caused by the total length of the 4 cookie 'files' in the HTTP protocol. Given that reducing the size of a specific cookie was quite problematic, it was recognised that the tree and sitemap menus produced cookies of the same format, although originally each menu could save its own independent open status. The short-term solution therefore adopted is for the tree and sitemap menus to share the same cookie, which means that opening either the tree or sitemap menus to a given level is then reflected in the other menu, when the next page is loaded. Personally, on reflection, this approach seems to have several advantages and comes with the clear benefit that it avoids the 'here-and-now' server problem as well as supporting the continued expansion of the websites for the immediate future. As such, it has bought time to consider and reflect on the implications of deploying a long-terms solution based on 'HTML5 web storage'.

Long-Term Solution

The idea of web storage, as defined by HTML5, comes in two favours known as 'sessionStorage' and 'localStorage'. From a programming perspective, each method is essentially identical in form, except for the change in syntax; however, operationally sessionStorage is automatically deleted on exiting the browser, while localStorage is retained.

So which is preferred as a replacement for the current cookie application?

In the context of the cookie application, sessionStorage is preferred, because retaining the open status of the tree menus is only considered important per session and has the benefit that the overhead of clearing local storage is not left up to the client-user to tidy up. However, there are two other clear benefits that HTML5 web storage has over cookies:

  • The data is always saved locally on the client-side system
  • The amount of data that can be saved is dramatically increased.

As previous implied, when a website is accessed on a web server by a client-side browser, cookies are not saved locally, but rather transmitted back and forth between the server and the client. This leads to problems, because the server invariably put a limit on the size of a HTTP request, which in-turn puts an equally finite limit on the size of the cookies, even though the server makes no use of the cookie data in this specific application. In this respect, sessionStoarge is almost purpose built for this type of application in that its allows relatively large amounts of data, e.g. 10Mbytes as opposed to 4Kbytes, to be stored locally on the client-side system, which circumvents any size restrictions imposed by the server and, in addition, removes the unnecessary overhead of transmitting the data between the server and client and back again.

So can sessionStorage be used to immediately replace cookies in this case?

A version of this website has already been developed that completely replaces the need for any cookies through the application of sessionStorage, which has all the benefits previously outlined. This approach has also be successfully tested against the latest versions of all 5 browsers supported, but has not yet been deployed.

So what is the problem?

Basically, we need to return to the issues associated with 'browser variance' and 'backward compatibility' as highlighted at the start of this discussion. We might begin to examine these issues using the following HTML file as a test example, designed to highlight a number of variances in operation, when run under different browsers. As such, this code can be cut and pasted into any <file.html> on your own 'local' system and tested against any number of browsers.

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var myData="set/get data";
function setStorage()
    {
    try
        {
        if(sessionStorage == undefined)
            {
            alert("Set: Storage undefined");
            return;
            }
        sessionStorage.setItem('myLabel', myData);
        }
    catch(err)
        {
        alert("Set: exception error");
        return;
        }
    }
function getStorage()
    {
    try
        {
        if(sessionStorage == undefined)
            {
            alert("Get: Storage undefined");
            return;
            }
        alert(sessionStorage.getItem('myLabel'));
        }
    catch(err)
        {
        alert("Get: exception error");
        return;
        }
    }
setStorage();
getStorage();
</script>
</head>
<body>
Hello world
</body>
</html>

In the <body> of this HTML file, we see the standard 'hello world' to be displayed, although this has nothing to do with the purpose of this example, other than to prove the browser is working at a basic level. Therefore, our interest is focused on the javascript code in the <head> section of the example file. In essence, there are 2 functions, i.e. setStorage() and getStorage(), which test if, and how, the sessionStorage is supported on your browser.

Note: when running on your 'local' system, the HTML file is simply opened by a browser without the file being associated with any web host. For example, if the file is run under a local host, such as Microsofts Internet Information Service (IIS), the results will be different to that described below.

The <try/catch> blocks in both functions allows the code to be tested for an error, which if it occurs causes the exception to be trapped by the <catch(err)> block. Within each <try> block, the first statement tests to see if sessionStorage has been defined in the local browser and, if not, an appropriate message is displayed via the alert() statement before the code simply returns to the caller. Clearly, if this first statement causes an error, the path is different, as control is passed to the <catch> block, which displays the exception message before returning to the caller. Finally, if no exception occurs and sessionStorage is defined, the message displayed should be 'set/get data'. As such, we have a bit of code that can test for variance in the browser operation in a local system.

Note: It will be stated up-front that the example code above works, as expected, in all 5 browsers tested when run on a web server or local host, such as IIS. However, this desirable consistency is not reflected when run locally and also raises concerns as to the exact operation when run using older versions of these browsers, before they supported HTML5 webs storage.

As the note above implies, the resulting local operation is not consistent when compared against the 5 selected browsers. The table below shows the variance in browser operation, for both sessionStorage and localStorage modes, when run as a local system.

Browser Local Host
IE 9.0.8 session Undefined session Yes
local Undefined local Yes
Firefox 9.0.1 session Exception session Yes
local Yes local Yes
Chrome 16 session Yes session Yes
local Yes local Yes
Safari 5.1 session Yes session Yes
local Yes local Yes
Opera 11.6 session Yes session Yes
local Yes local Yes

Based on the table above, the latest version of Chrome, Safari and Opera all supported both the session and local modes of web storage, although Opera can have problems with the file-directory specification on local systems. Apparently, Microsofts IE9 only supports web storage when run on a host and the test code shows that the storage, i.e. session or local, is undefined, when run in a local system. The operation of Firefox seems more inexplicable in that localStorage works locally, while sessionStorage actually causes an exception.

Why worry about local operation as long as it works on a hosted server?

For many people, this may be a non-issue, but it is very convenient to be able to test and operate a client-side website in a local system without the hassle of supporting a local host, such as IIS. As far as this website is concerned, this was the case prior to introduction of HTML5 web storage, with the one exception of Chrome's support of local cookies. Of course, Google might argue that cookie operation is implicitly linked to a web server, even though all its competitors support local cookie operation. However, web storage seems to be implicitly linked to client-side data storage applications and, in this sense, independent of the web host, such that one might question why Microsoft has taken its approach.

But how does this affect the decision to replace cookies with web storage?

Examination of the <if/then/else> permutations in the code above, in conjunction with the results in the table, suggests that simply replacing cookies with sessionStorage will be messy, if local operation is to be supported. However, even if we ignore the requirement for local web operation, there is sufficient concern raised by the example code and table above, when extended to older versions of all these browser in which web storage is not supported. Again, it is unclear as to the total scope of 'undefined' and 'error exception' coding that might be required, which will then be compounded by the complexity of having to simultaneously support the original cookie mechanisms, when web storage is not available in older browsers.

So does this mean the web storage will never be supported by this website?

No, based on the 80/20 rule, there will come a time when +80% of users will use browsers that support web storage, such that the cookie mechanism will simply be turned off and the feature of saved tree status will simply not be available on older browsers. As far as local system operation is concerned, there are browsers that seem to have no problems, or technical objections, in fully supporting this mode of operation. Of course, there is also the hope that all browsers might converge to a consistent approach to local operation, as there appears to be no obvious technical reason for the different approaches, other than some vendors refusing to correct any initial approach taken in the implementation of a given 'feature'.

Footnote

Clearly, this discussion has only cited one example where browser variance and backward compatibility can lead to major implementation issues in connection with the design and support of a website. Clearly, attempting to address all variance in operation across all browsers and older versions in use could prove time consuming and possibly a futile task. As such, the 80/20 rule is often a pragmatic way to reach some practical compromise. However, developments in all the web related protocols would seem to suggest that the following long standing adage is still alive and well:

The nice thing about standards is that there are so many to choose from!