Improve the performance of Web applications, identify bottlenecks, and speed up client content __web

Source: Internet
Author: User
Tags border color object model pack ibm developerworks stringbuffer

Article from: IBM DeveloperWorks

Introduction: as a Web user, we know that the speed at which a page is loaded or refreshed is critical to its success. This article will help you better understand the factors that affect the performance of your Web application. Learn to identify these problems and find bottlenecks in the client content. Explore the performance issues of JavaScript, DOM, CSS, and Dojo widgets. An example will be shown to properly tune the Dojo widget using YSlow and Firebug.


Rich Internet Applications (RIAs) is very popular in the area of Web 2.0. To provide a fresh, chic user experience, many Web sites use JavaScript or Flash to move complex content from the backend server to the foreground client. This provides a convenient, innovative, and fluent user interface (UI) if the data is low. If you want to transfer a large amount of content from the server to the client and render in the browser, performance will decrease significantly. The challenge is to find the bottleneck and determine the solution.

It is more difficult to adjust performance problems in the browser than in Java applications. Developers can debug JavaScript in a variety of browsers in a much smaller way. In Mozilla Firefox, you can use Firebug to debug JavaScript, but you still can't adjust a lot of performance issues, such as browser rendering consumption time. To address these issues, it is necessary to develop browser Plug-ins to monitor time responses and to determine other corresponding solutions such as partial rendering or deferred loading.

Learn to diagnose performance problems in Web applications, find bottlenecks in client content, and adjust performance.

JavaScript and HTML DOM

JavaScript is the most popular scripting language used on the Internet. Tens of thousands of web page designers use JavaScript to improve design, validate forms, check browsers, and create cookies. The HTML document Object Model (DOM) defines a standard way to access and manipulate HTML documents. It represents an HTML document as a node tree that contains elements, attributes, and textual content.

You can access all nodes in an HTML document and manipulate them by using HTML dom,javascript. Many mainstream browsers support JavaScript and HTML DOM, and many Web sites use them as well. The performance that they use significantly affects the performance of the entire RIAs.

JavaScript Performance and functions

In JavaScript, use a function when a feature is needed. Although there are cases where you can substitute a string for a function, we recommend that you use the function as much as possible. In JavaScript, a function is precompiled before it is used.

For example, look at the eval method in Listing 1.
Listing 1 The Eval method uses strings as arguments

function Square (input) {
  var output;
  Eval (' output= (input * input) ');
  return output;

The Eval method calculates the squared value and outputs the result, but the performance is poor. This example uses string output= (Input*input) as an argument to the Eval method and cannot be precompiled with JavaScript.

Listing 2 shows a better way to accomplish this task.
Listing 2. Eval method using a function as a parameter

function Square (input) {
  var output;
  Eval (new function () {output= (input * input)});
  return output;

Use a function instead of a string to make sure that the code in the new method is optimized by the JavaScript compiler.

function scopes

Each scope in a JavaScript function scope chain contains several variables. It is important to understand the scope chain so that you can take advantage of it. Listing 3 shows an example of a function scope.
Listing 3. function Scope

function test () {
  var localvar = ' Test ';
  Test1 (this. localvar);
var pagename = document.getelementbyid ("pagename");

Figure 1 shows the scope chain structure.
Figure 1. Scope Chain structure

Using local variables is much faster than using global variables, because the farther the scope chain is, the slower the parsing is.

If you have a with or Try-catch statement in your code, the scope chain is more complex. Figure 2 shows the scope chain of the Try-catch statement.
Figure 2. Try-catch Scope chain Structure

String functions

The least desirable function in JavaScript is string concatenation. I usually use the + number to implement the connection. Listing 4 shows one of these examples.
Listing 4. String concatenation

var txt = "Hello" + "" + "world";

This statement creates several intermediate strings that contain the result of the connection. This creates and destroys strings continuously in the background, resulting in very low string concatenation performance. Earlier browsers did not optimize for such an operation. We recommend that you create a StringBuffer class to implement, as shown in Listing 5.
Listing 5. StringBuffer Objects

function StringBuffer () {
this.buffer = [];

StringBuffer.prototype.append = function Append (val) {
 This.buffer.push (val);
 return this;

StringBuffer.prototype.toString = function toString () {return
 This.buffer.join ("");

All properties and methods are defined for a string object (not a value). When you reference a property or method of a string value, the ECMAScript engine implicitly creates a new string object with the same value before the method executes. This object is used only for a specific request and is re-created the next time a method of a string value is used.

In this case, the new statement is used for strings whose methods are called multiple times.

An example of a new string object is shown in Listing 6.
Listing 6. Example of creating a new string Object

var str = new String ("Hello");

Stringobject.indexof is faster than Stringobject.match. When searching for a simple string match, try to use indexOf instead of a regular expression to match.

Try to avoid matching in long strings (10KB and above) unless you have no choice. If you are determined to match only a particular part of a string, use the substring instead of the entire string comparison.

DOM Performance

This chapter briefly describes some of the things you can do to improve the performance of your DOM.

Redraw (Repaint)

When the previously invisible content becomes visible, the DOM is redrawn, and vice versa. Redrawing is also called repainting. This behavior does not change the layout of the document. Changing the appearance of an element without changing its size, shape, or position can trigger a redraw.

For example, adding a border to an element or changing the background color triggers a redraw. The performance of redrawing is costly; it requires the engine to search all elements to determine which are visible and which must be displayed.

Reflux (reflow)

Reflux is a more significant change in the gravity plot. In reflux: To manipulate the DOM tree. The style that affects the layout changes. The ClassName property of the element will change. browser window size changes.

The engine will return the associated elements to determine where the parts are displayed. Child elements are also returned to reflect the new layout of the parent element. Elements behind elements in the DOM are also returned to compute the new layout, as they may have been moved at the time of the initial reflow. Ancestral elements are also returned because of changes in the size of their descendants. Finally, all content is redrawn.

Each time you add an element to the document, the browser returns to the page to calculate how all the content is positioned and how it is rendered. The more things you add, the more times you return. If you can reduce the number of individual elements to add, the browser will return fewer times, and run faster.

CSS Performance

Place the cascading Style Sheets (CSS) on top. If the style sheet is placed at the bottom, it is finally loaded. For a few seconds, the page is blank, the browser waits for the stylesheet to load, and then something else on the page can be rendered-even static text.

In Internet Explorer, the @import is the same as using the <link> effect at the bottom. We recommend that you do not use.

Abbreviated properties

Use abbreviated attributes to set several properties at once in a declaration instead of one declaration per property. With abbreviated attributes, you can reduce the file size and reduce the amount of maintenance.

For example, you can set a background, border, border color, border style, border side (top border, right border, bottom border, left border), border width, font, margin, outline, padding properties.

CSS Selector

The CSS selector matches by moving from right to left. As shown in Listing 7, the browser must traverse each anchor element in the page to determine whether its parent element ID is aelement.
Listing 7. Selector is matching from right to left

#aElement > a{

If you remove > from your code, as shown in Listing 8, performance is worse. The browser checks all anchors in the entire document. Instead of just checking the anchor's parent element, you look up the document tree to find the ancestor element with the ID aelement. If the element being examined is not a descendant of Aelement, the browser is searched along the tree of the ancestor element until the root of the document.
Listing 8. If not, the performance is worse

#aElement a{

Best practices

This chapter will outline the best practices that can help you improve the performance of your Web application.

Reduce the number of HTTP requests

Each HTTP request has overhead, including finding DNS, creating connections, and waiting for responses, so cutting unnecessary requests can reduce unnecessary overhead. To reduce the number of requests: merging files. Merging scripts that are always used together into the same file does not reduce the total size, but will reduce the number of requests. You can also merge CSS files and pictures in the same way. You can implement automatic file merging: During the build phase. Using the <concat > tag, run Ant to merge the files. At run time stage. Enable the Mod_concat module. If Httpserver is Apache, use Pack:tag as the JSP tag Library to merge JavaScript and style sheet files. (Pack:tag is a jsp-taglib that reduces, compresses, and merges resources, such as JavaScript and CSS, and caches them in content or normal files.) ) using CSS sprites. Combine the background picture into a single picture and use the CSS Background-image and Background-position properties to display the picture part you want. You can also use inline pictures to reduce the number of requests.

Post-load component

Only the required components are rendered, and the rest can wait. It is best not to render too many components at once.

In some cases, you can use a back-mount load. Because components outside of the browser's viewable area can be loaded later, the initial rendering is invalidated when these builds enter the viewable area soon.

Some javascript can be loaded after the OnLoad event, such as after initial rendering in JavaScript, and drag an element.

Front Load Component

The front load component allows you to use the browser's idle time to request future components (such as images, styles, and scripts). When a user accesses the next page, the page loads much faster if most of the components are already loaded in the cache.

There are two kinds of preload: unconditional: Once the onload is triggered, some additional components are obtained. Conditional: According to the user's action, speculate the direction of the user's next step and the corresponding front loading.

Put the script on the bottom

Scripts can cause problems because they may hinder concurrent downloads. When downloading scripts, browsers do not start other downloads-even if they are located on different hosts. Place scripts, such as style sheets, at the bottom to ensure they are downloaded after other downloads are complete.

You can also use a delay script, which is supported only by Internet Explorer. The DEFER property indicates that the script does not contain document.write (). This tells the browser that they can continue to render.

Using the No cookie domain component

When a browser makes a request to a static picture and sends cookies with it, the server does not use those cookies. Because these cookies only cause unnecessary network traffic, make sure that the static component is requested with no request. These static components are then saved using subdomains and hosts.

Place JavaScript and CSS on an external

Using external files in the real world usually makes the page run faster because JavaScript and CSS files are cached by the browser. JavaScript and CSS inline with HTML documents are downloaded each time the HTML document is requested. This reduces the number of HTTP requests required, but increases the size of the HTML document. On the other hand, if JavaScript and CSS are in a browser-cached external file, the size of the HTML document is reduced without increasing the number of requests.

RIA Widget Performance

Mainstream RIA Ajax frameworks, such as ExtJS, YUI, Dojo and others, offer a few nifty widget libraries to enhance the user experience. Compared to other frameworks, Dojo is more powerful in enterprise development because: the Dojo offline API for object-oriented programming (OOP) encoding cross-platform Local data storage supports DataGrid, 2D, and 3D graphics (the Chart Component provides Easier way for browsers to show reports)

Dojo is widely used in many websites. We will use Dojo examples to analyze the performance of RIA widgets. The Dojo widget adjustment tool can be used for specific situations, with Page Speed, rock Star Optimizer, and Jiffy. We strongly recommend the use of YSlow and Firebug.


YSlow analyzes Web page performance by examining all the components on the page, including those created by JavaScript, based on a set of High-performance Web page guidelines. YSlow is a Firefox plug-in that integrates Firebug Web development tools, provides recommendations for improving page performance, summarizes component performance, displays page statistics, and provides tools for profiling.

Figure 3 shows the information on the YSlow Grade tab.
Figure 3. YSlow Grade Tab

The YSlow Web page is based on 22 testable rules, sorted by importance and effect below. Research shows that web page response times can be increased by 25% to 50% by following these rules: Minimizing the number of HTTP requests. Use a Content publishing network (CDN). Add Expires or Cache-control head. Compresses content with Gzip. Place the style sheet at the top. Place the script at the bottom. Avoid the use of CSS expressions. Place JavaScript and CSS outside ... Reduce DNS searches. Streamline JavaScript and CSS. Avoid using redirects. Deletes a duplicate script. Configure ETags. Enable Ajax to be cached. Use Get for Ajax requests. Reduce the number of DOM elements. Eliminates the 404 error. Reduce the cookie size. Use a domain without cookies for the component. Avoid using filters. Does not measure picture size in HTML. Make the Favicon.ico as small as possible, and can be cached.

The YSlow Statistics in Figure 4 compares the page sizes of the null-cached access user to the user who previously visited the page.
Figure 4. YSlow Statistics Tab

The Components tab shows each component and related performance information. For example, you can see if the component is compressed by gzip, or if the ETag has content (if any). The component size and overtime time are also displayed in the Components tab, as shown in Figure 5.
Figure 5. YSlow Components Tab


Firebug is integrated with Mozilla Firefox, allowing you to have a lot of development tools handy when browsing the site. You can edit, debug, and monitor CSS, HTML, and JavaScript on your Web pages in real time.

You can use the Firebug Net panel, as shown in Figure 6, to monitor the HTTP traffic generated by your Web pages. It shows the user all the collected and calculated information. Each entry represents a request/response back to the page.
Figure 6. Firebug Net

The Firebug Console panel, shown in Figure 7, provides two ways to monitor code performance.
Figure 7. Firebug Console Panel

profile for a particular function, use Profiler. JavaScript Profiler is a Firebug feature that can be used to measure the execution time of each JavaScript code. Use JavaScript Profiler to improve the performance of your code, or to see why a function is running too long.  It is similar to Console.time (), but JavaScript Profiler can provide more details of the internal process of the code. console.time () for specific code snippets, use Console.time (). The console displays the results of the command you entered into the command line. You can use the Console.time (timename) function to measure how long a particular code or function executes.   This feature is useful for improving the performance of JavaScript code. Listing 9 shows a sample.
Listing 9 console.time () examples

var timename = ' measuringtime ';  
Console.time (Timename); Start of the timer for   
(var i=0;i<1000;i++) {  
//do something  
console.timeend (timename);  End of the timer

MEASURINGTIME:XXMS will be displayed in the console.

Dojo Widget Performance

This chapter explores ways to improve the performance of Dojo widgets.

Load cost

such as "Improving performance of dojo-based Web Applications" (E. Lazutkin, Feb 2007) points out that most of the Dojo users ' first impression of it is that it's very large. For example, the is 19M, even the compressed has 4.5M. Most of the files in the minimalist version are redundant and will never be used. All dojo versions have copies of all the dojo files and custom dojo.js files that incorporate all the common files. The best way to reduce the cost of loading is to use the appropriate Dojo version.

Dojo.js can activate Dojo objects and dynamically load the remaining modules unless they have been loaded in an optional part of the dojo.js. When the browser loads the Dojo.js file for the first time, it uploads and installs the following files: Dojo boot code dojo loader common modules

To reduce the load time, you need to consider which version is best for your application. Otherwise, you need to customize a Dojo version. For more information about Dojo documentation, see the resources chapter.

Parsing costs

To minimize Dojo widget resolution costs, use the following two methods to optimize initialization: Tag instantiation You can create a Dojo widget with an HTML tag by adding the Dojotype property, as shown in Listing 10. This method operates on the premise that Dojo.parser is included in the Dojo.require ("Dojo.parser"); , and djconfig= "Parseonload:true". This is an easy way to declare a component in lightweight code. All labels with dojotype properties on the page are automatically parsed after the document is loaded. This approach is handy for small applications, but can significantly increase startup time for Web applications with a large number of HTML. The parser accesses all the elements to check whether you want to parse. Use a configuration file, as provided in Firebug.

Consider widget initialization If you find that you spend too much time on dj_load_init (), modulesloaded (), or other similar initial load content.

Listing 10. Create a dojotype Dojo widget

Id= "Errordialog" dojotype= "Dijit. Dialog "title= ' Dialog1 ' class=" Pop-window "/>

Code Instantiation Dojo is an OOP framework, so you can use new to create widgets. To create a widget, you must enter two parameters: a JSON object with attributes and the element to resolve.   Each widget requires at least two statements.   Listing 11 is a sample.

Listing 11. Create a Dojo widget with JavaScript new


Improve resolution Performance

To optimize the structure and performance of your code, consider promoting resolution when you create widgets. Disable automatic resolution by setting Parsewidgets to False, and then create an array to set the ID of the element, as shown in Listing 12. You can also dynamically put the ID of the new element at run time. When the document is loaded, the Dojo.foreach () is used to parse all the elements in the array.
listing 12. Resolving widgets by iterative Searchids


listing 14. Rendering data, Updating grid header view
"Sorcolidx" is the index of the ' column to be sorted updategridaftersort:function (SORTCOLIDX) {//render the DA
	Ta of the grid var store = new (;
	Grid.setstore (store, NULL, NULL);
	Grid.update ();
	Update the header view of the gird var headernodeobjs = document.getelementsbytagname ("th"); for (var i = 0; i < 2; ++i) {//' gridLayout ' is a global array defining the layout of the grid var Headernodeobjname
		= Gridlayout[0].cells[0][i].name;
		var headernodehtml = [' <div class= ' Dojoxgridsortnode ']; if (i = = sortcolidx) {headernodehtml = Headernodehtml.concat ([' ", (sortascending = = True)?  ' Dojoxgridsortup ': ' Dojoxgridsortdown ', ' ><div class= ' Dojoxgridarrowbuttonchar ' > ', (sortascending = True) 
			' ▲ ': ', ' </div ><div class= ' dojoxgridarrowbuttonnode ' ></div > '];
			headernodehtml = Headernodehtml.concat ([Headernodeobjname, ' </div> ']); Headernodeobjs[i].inneRHTML = Headernodehtml.join ("");
		Break }

Find in GridLookup functions can cause poor performance when the grid has large amounts of data, especially when the grid supports real-time lookups and fuzzy matching features.   The solution is to cache data with additional storage space before they are converted into JSON objects used in the data store, which avoids a large number of function calls, such as the getitem of the data store. Listing 15 shows a sample.

listing 15. Cache data that is fetched from the database into an array and find

//fetch data from database Getdata:function () { function callback (ResultSet) {//resultset is a array of records fetched from database and make variable//rawdata refe
R to it into cache it in memory Globalvaribles.rawdata = ResultSet; Convert the raw data ResultSet to JSON for data store Use Globalvaribles.datajson = Jsonutil.convert2json (ResultSet)
} dbutil.fetchall (callback);
	}//search functionality Search:function (col, value) {if (value = NULL | | value = = "") {return;
	}//used here var rawdata = Globalvaribles.rawdata;
	var newresults = []; for (var i = 0; i < rawdata.length i++) {var = rawdata[i];//fuzzy match if (Result[col].tolowercase (). Inde
		XOf (Value.tolowercase ())!=-1) {newresults[newresults.length] = result;
}//render The new results gridmanager.rendernewresults (newresults); }

Delay loading mechanism The Dojo grid originally supported the deferred loading mechanism, which improves performance and provides a better user experience. Delay loading in the Dojo grid means that some data is rendered in the data store, but not all grids display the rest of the data when you drag the scroll bar.

By default, the delay-loading mechanism is not enabled by the grid, and must be explicitly started. Listing 16 shows the startup in two ways. The Rowsperpage and Keeprows properties are key components.

listing 16. Launch Demo loading mechanism

	            The programmatic way
	            var grid = new Dojox.grid.DataGrid ({
	            store:store,//data store
	structure:gridlayout , 
	rowsperpage:10,  //render rows every time
	keeprows:50,		//keep rows in rendering cache
} , "Grid");   
The declarative way using HTML label
dojotype= "Dojox.grid.DataGrid" id= "
	grid" store= " Store "structure=" GridLayout "
	query=" {ID: ' * '} ' 
	rowsperpage= ' keeprows= ' >
	<!--  Other definitions  -->

Pre-loading mechanism pre-load mechanism can load the rest of the data in advance, even if the user is only temporarily used. For Dojo grids, there may be a lot of data in the data store, and the user may drag the scroll bar to view the rest of the data. If there is a lot of data in a page, it's not convenient to look at a particular line.   Use the front mechanism and paging technology to make it easier to view (similar to Google's paging bar) and get better performance.

Listing 17 shows the basic implementation of paging technology. First, you construct a JSON object for the data store to use for the initial paging bar, and then add some new JSON objects when the user clicks the last page of the page-bar.
listing 17. Start by building some JSON objects and switching them as needed

//fetch data from database and convert them to JSO N Objects getdata:function () {function callback (ResultSet) {globalvaribles.rawdata = ResultSet;//"Convert2jsons" M
		Ethod convert the raw data to several JSON objects//stored in Global array "Datajsons".
	Globalvaribles.datajsons = Jsonutil.convert2jsons (ResultSet);
} dbutil.fetchall (callback);
}//initial status var datastore = new ({data:globalvaribles.datajsons[0]});
var Grid = new Dojox.grid.DataGrid ({Store:datastore, Structure:gridlayout,}, "grid");
Grid.startup ();  Assuming that's user clicks the i-th item in the paging bar, we just update the data//store for the grid simply and
The performance is still very good.
Datastore = new ({data:globalvaribles.datajsons[i-1]});
Grid.setstore (datastore, NULL, NULL); Grid.update (); 


In this article, you learned how to identify some of the problems or bottlenecks in your Web application. You now have some tools, tips, and tricks to use to adjust and improve performance for your users.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.