View source | View content page | Page history | Printable version   

Projects:Performance Review/PageSize and Caching

What and how to measure?

One point in measuring Performance is the amount of requests which are issued by a browser and the amount of data which is transferred to the browser to execute a specific action / open a specific window.

One way to capture this data is to enable the logging of each request (and the response) sent to tomcat, which can easily be done by enabling the tomcat access log. In this log a line is recorded per request which among other info records:

Saving the relevant pieces of this log-output the browser behavior regarding caching or re-requesting i.e. javascript libraries can be observed and the total amount of data transferred to render one page can calculated.

The following table summarizes the results for examining the requests for the cases of an empty browser cache for executing a login an opening the product page after logging in.

empty cache #req/#bytes primed cache #req/#bytes
Login 96 / 1.378.186 16 / 347.453
Login + Product 148 / 1.744.964 22 / 576.588
Product 88 / 366.778 6 / 229.135

The following splits up the number for the first row which shows the login and the menu loading and the last row which represents opening the product window (edit view) for the case where the browser cache is already populated with the cacheable portions.

The data used in the login process is only loaded once during the login and the menu portion of it is loaded again on each role change.

The size of the menu as configured with the sample data and using the 'Openbravo Admin' role is about 306kb. As this default role has all access permissions nearly all available menu entries are included in this so it can be seen like some upper bound for the menu size.

The workflow which is executed for measuring the 229.135 bytes for the product page consists of opening the (empty) product page. Click ok on the automatically opened window (search/filter popup) and then loading the product page which the result (a single product in edit mode). The 6 requests needed for this are 2* the product page in edit mode, 1* the page for the search popup and 3* a dynamically generated page for requesting the potentially visible error messages translated to the currently select user interface language.

The main factor regarding size here is the real product page. When looking at the same flow for viewing the business partner page (empty page, search popup, page with one business partner) one gets similar sizes:

As a general, simplified statement a generated page is roughly 80 - 100 kilobytes in size depending on the complexity / number of fields on the page. The size of error-messages and the search popup can be omitted in comparison to loading the relevant data page two times.

In addition the look at the flow to open the product page (primed cache) shows, that no a single static resource (css,image,js-library) is requested by the browser again, after it has been stored in the browser cache. This point is important here as the number of requests to load a page with a network round-trip time is an important factor in the total time needed to transfer a page. The browser does not transfer the static data again and even does not request the data with an additional "If-modified-since" header to check if its still up to date. This browser behavior is consistent across Firefox 3 (on Linux) and Internet Explorer 7 (on Windows).

As a consequence when testing the application behavior with a tool like JMeter, all requests for static resources (css,images,js-libraries) can and should be omitted to catch the most common case of an already filled browser cache. Only when omitting these the request-pattern and server load is comparable to the real browser behavior.

This slimmed requests do not cover the case of an empty browser cache which can occur when using a clean client instance. In this case still a lot of data is requests in many requests, which make the first access to the application a lot slower than any subsequent ones.

Influence of HTTP compression and JS/CSS minimization

We did some additional measurements which show the impact of HTTP compression and JS/CSS-minimization on the size of the files as they are transferred to the client.

HTTP compression means dynamic compression of all or some files just before they are transferred to the browser. The browser uncompresses these files on the fly so that there is no user-visible change.

JS/CSS-minimization means transforming the Javascript and CSS-files before deploying the application to minimize the filesize (i.e. remove unneeded whitespace, comments, ...)

The HTTP compression can be done by two different methods. Either the servlet container i.e. tomcat) can be configured to selectively compress some or all outgoing files) or an additional apache server can be used in front of the servlet container and the compression can be moved to the apache server.

One benefit of using an additional apache server is that it can be configured to do logging per transferred file showing uncompressed size, compressed size an the compression ratio.

The following shows the results obtained by this logging for some selected (bigger) files.

filename Uncompressed size Compressed size Compression ratio
Openbravo_ERP_240.css 240kb 22kb 9%
utils.js 147k 29k 19%
dojo.js 357k 93k 25%
Empty Bpartner edit view 83k 10k 11%

The compressed sizes of this resources are significantly smaller as the original files and when applied in a bandwith limited environment should lead to a very good decrease of the response times as the transfer times decrease with the saved size.

One aspect of the dynamic output compression is added load on the server side to do the compression of the content on every request. But tests with multiple users showed no noticable impact on the tested flows on the application server so that HTTP compression should always be enabled to reduce amount of data transferred.

In addition we measured the saving gained by using static JS/CSS-minimization. The interesting point in here was if there is a gain by using the minimization on-top of the dynamic compression or not.

For the JS/CSS-minimization we use the YUI compressor tool.

The following table summarizes the gains comparing dynamic compression (only) and combined usage of minimization and dynamic compression.

filename Uncompressed size size (compressed) size (minimized and compressed)
Openbravo_ERP_240.css 240kb 22kb 17k
utils.js 147k 29k 15k
dojo.js 357k 93k 83k

This table does omit the values for the Business Partner edit view as only static not changing content is minimized. The additional savings are not as big as the ones gained by using the dynamic compression but still show some measurable improvement. As the usage of minimization comes with a one time cost at compile time only it can be easily added.

One downside of using the minimized JS- and CSS-files is that they are not easily readable anymore. But this is easily addressed by making the minimization optional and compile time, so it can be disabled.

Retrieved from ""

This page has been accessed 3,998 times. This page was last modified on 8 June 2012, at 05:29. Content is available under Creative Commons Attribution-ShareAlike 2.5 Spain License.