Using AJAX to Improve the Bandwidth Performance of Web Applications
来源:互联网 发布:电子书编辑软件 编辑:程序博客网 时间:2024/04/29 07:51
Introduction
Being a performance company, we are always interested in the impact of new development techniques on the performance of web applications. We have numerous customers who have performance problems due primarily to the size of their web pages. Put another way - the pages are simply too big to achieve the desired performance goals with the available bandwidth. In some cases, the page consists primarily of content that is common between many pages. For instance, a header, footer and navigation menu that change infrequently, if at all, during the use of the application. This suggested that if the application was only updating the part of the page that needed to change, a considerable amount of bandwidth could be saved.
The Goal
In order to test the theory, we decided to see if we could cut the bandwidth use of an application by at least 50%. We selected a rather simple internal data-analysis application. The application consists of a typical page layout with a central section containing the changing content. The header, footer and navigation menu do not change during the application operation. We modified the application so that it can be accessed in either traditional (page-refresh) mode or AJAX mode. We then used our measurement tool (Web Performance Analyzer) to record and analyze the bandwidth utilization of each application.Results
The first result of this effort surprised us a little. With all the talk of AJAX frameworks, we expected to have a difficult time choosing an appropriate AJAX framework to use in our application. After trying a few simple experiments with a few popular frameworks, and learning just enough Javascript to be dangerous, we settled on a simple collection of javascript functions to accomplish our goals. We were able to pull a few code snippets from various Javascript/AJAX tutorials around the 'net and with less than 100 lines of javascript (and some refactoring of our web-app) we converted the application to use AJAX. No frameworks needed.The second result confirmed our expectation - we were able to cut the bandwidth usage of the application by 61%. The chart below shows some bandwidth statistics for the two versions of the application:
44k
10k
210k
AJAX
47k
2.5k
81k
TOTAL BANDWIDTH SAVINGS > 61%
Where did the savings come from?
Below are screenshots from our measurement tool (Web Performance Analyzer) showing the page/url transaction sizes for the original application (page-refresh mode) and the AJAX version. As you can see from the list of URLs and sizes below, the AJAX-mode application actually made the first page of the application larger. In our test, it was approximately 3k larger. This is not surprising, since this page contains the additional javascript required to drive the AJAX mode. If an AJAX framework had been chosen, we would expect this increase to be considerably larger.Most notable is that the typical page size decreased from ~10k to ~2.5k - a reduction of 75%.
Figure 1 - Bandwidth requirements in page-refresh mode
figure 2 - bandwidth requirements in AJAX mode
How We Did It
To achieve the bandwidth savings, we made a handful of modifications to our application. Application-mode switch
First we added an application-mode switch. This used a context parameter in the web-application descriptor that the application could query to determine if it was in AJAX or page-refresh mode. Note that this step would be unnecessary in most applications.HTML Form widget changes
Next we modified the HTML form widgets to change the form-submission mechanism. As an example, here is the starting tag for a SELECT element (drop-down list) before and after the modifications:<SELECT name="type" onChange="window.document.theform.submit()">The SELECT element will now call a javascript function (see below) instead of using the browser to submit the form.
<SELECT name="type" onChange="submitForm()">
HTML SPAN element around the form
In order to mark the section of HTML that is to be replaced dynamically by the content returned from the server, it is placed inside a SPAN element named with an identifier we can use in our javascript functions:<span id="content_area">
Javascript functions
Next we wrote or scavenged several javascript functions to perform the AJAX-mode form submission and page update.The first is the submitForm() method referenced in the SELECT elements (described above). This method is called to replace the browsers form-submission logic. The submission is accomplished in two steps:
- Build a string containing the content to submit.
- Submit the content to the specified URL with a callback method to be invoked when the operation is completed.
submitForm()
function submitForm()
{
var content = convertFormDataToPostContent(window.document.theform);
doPost('/office/UsageAnalyzer', content, 'processResult');
}
Look at the third parameter in the doPost() method call: 'processResult'. This is the name of our callback method. When the asynchronous method is completed, this method will be called with the result.
The job of the processResult() method (below) is to update the document with the result of the post. Note that the 'content_area' parameter to the getElementById() method is the same as the id of the SPAN element we added to our HTML.
processResult()
function processResult(result)
{
document.getElementById('content_area').innerHTML = result;
}
The work of submitting the content in a POST transaction to the server is relatively simple. It creates a browser-specific request object, submits the content and creates a function used to perform the callback with the content returned by the server. This code was scavenged from the Internet and can be readily found in many AJAX articles or frameworks.
doPost()
function doPost(url, content, callback_name)
{
var async_request = false;
// Mozilla/Safari
if (window.XMLHttpRequest)
{
async_request = new XMLHttpRequest();
async_request.overrideMimeType('text/xml');
}
// IE
else if (window.ActiveXObject)
{
async_request = new ActiveXObject("Microsoft.XMLHTTP");
}
async_request.open('POST', url, true);
async_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
async_request.onreadystatechange = function()
{
if (async_request.readyState == 4)
{
response_content = async_request.responseText;
eval(callback_name + '(response_content);');
}
}
async_request.send(content);
}
The form-field conversion method traverses the list of fields in the form and encodes them into the proper format for submission as a form-urlencoded post. Again, this code was scavenged from sources on the Internet.
convertFormDataToPostContent()
function convertFormDataToPostContent(form_name)
{
var content_to_submit = '';
var form_element;
var last_element_name = '';
for (i = 0; i < form_name.elements.length; i++)
{
form_element = form_name.elements[i];
switch (form_element.type)
{
// Text fields, hidden form elements
case 'text':
case 'hidden':
case 'password':
case 'textarea':
case 'select-one':
content_to_submit += form_element.name + '='
+ escape(form_element.value) + '&'
break;
// Radio buttons
case 'radio':
if (form_element.checked)
{
content_to_submit += form_element.name + '='
+ escape(form_element.value) + '&'
}
break;
// Checkboxes
case 'checkbox':
if (form_element.checked)
{
// Continuing multiple, same-name checkboxes
if (form_element.name == last_element_name)
{
// Strip of end ampersand if there is one
if (content_to_submit.lastIndexOf('&') ==
content_to_submit.length - 1)
{
content_to_submit = content_to_submit.substr(
0, content_to_submit.length - 1);
}
// Append value as comma-delimited string
content_to_submit += ',' + escape(form_element.value);
}
else
{
content_to_submit += form_element.name + '='
+ escape(form_element.value);
}
content_to_submit += '&';
last_element_name = form_element.name;
}
break;
}
}
// Remove trailing separator
content_to_submit = content_to_submit.substr(0, content_to_submit.length - 1);
return content_to_submit;
}
Conclusion
In applications that have a significant part of each page containing content that is identical in multiple page requests, using AJAX-style methods to update only the relevant parts of a web page can bring significant bandwidth savings. Using less than 100 lines of javascript, we were able to quickly convert an existing web application to use AJAX page-update methods to drastically reduce (>60%) the bandwidth requirements of our sample application.It is important to note that the application converted in our test was ridiculously simple. Achieving the same bandwidth reduction on a sophisticated application will likely not be as easy, if it is possible at all. However, when applied to extremely large-scale applications or applications with very tight bandwidth considerations, savings of 10% could bring a hefty cost savings.
Future Directions
It would be interesting to test a more realisitic application that has been converted from a previous version to use AJAX in the method described here. If you know of such an application, please contact us!The impact on server CPU resources would also be an interesting study. However, given that none of the "fluff" on our pages requires any database queries or other processing work, our reference application may not be the best choice for this test.
If you have a preference for what you would like to see in future versions, please make your voice heard in our forum.
Feedback & Comments
An on-line forum is provided for discussing the details, results and merits of this report.
Version History
v1.0 - 1st public release (15 jan 06)
- Using AJAX to Improve the Bandwidth Performance of Web Applications
- Ten ways to improve testing, performance of Web 2.0 applications
- Using Covering Indexes to Improve Query Performance
- 10 Tips to Improve an ASP.NET Applications Performance
- pat 1055 how to improve the performance
- How to improve web services performance
- How to user SSE2 instructions to improve the performance of memory copy?
- Dojo: Using the Dojo JavaScript Library to Build Ajax Applications
- CSV ----- To improve the performance of Excel Output with reflection (Part 1)
- Performing a deep fetch of the `master` specs repo to improve future performance
- Performing a deep fetch of the `master` specs repo to improve future performance
- Performing a deep fetch of the `master` specs repo to improve future performance
- Using hardware layers to improve Android animation performance
- Yahoo web performance improve
- Improve performance using hash keys
- HOW TO Analyze ASP.NET Web Application Performance by Using the Performance Administration Tool
- The development of WEB Applications
- [MySQL]Improve performance of MySQL
- ORACLE常用命令
- FOB报价公式
- My sql 的InnoDB 介绍
- JSTL(JSP标准标签库)介绍
- JSP实现外部提交的例子(含源代码)
- Using AJAX to Improve the Bandwidth Performance of Web Applications
- Oracle Package中返回游标的写法和调用
- 忙碌的开始
- 关于JSP连接池
- marquee 的问题
- 《在小吃店遇见凯恩斯》读书心得小记 - Part 2
- Scott Mitchell 的ASP.NET 2.0数据教程之一: 创建一个数据访问层
- AJAX技术如何节省应用的带宽:多次交互,每次少量更新
- Scott Mitchell 的ASP.NET 2.0数据教程之二:创建一个业务逻辑层