Optimize your JavaScript, CSS and HTML code - nschonni/wet-boew GitHub Wiki

français

How to optimize your JavaScript, CSS and HTML code. Please add to and improve upon the techniques that already listed.

Table of Contents

Overview

Code optimization is now an important task with the Web Experience Toolkit taking a mobile-first approach in version 3.0. Where sluggish code may have minimal impact on desktop browser performance, it can result in very noticeable delays on mobile devices. That is why a main focus of WET v3.0 is performance optimization.

The WET v3.0 framework is already heavily optimized using code minification, consolidation and Base64 encoding. All of these result in significant performance increases but can still be bogged down by bloated and sluggish code. This page provides many tips for ensuring your code is as efficient as possible

JavaScript code optimization

  • Minimize the use of jQuery. jQuery can be a big help with DOM traversal and complex scripting scenarios but can be sluggish when dealing with simple and straight forward coding scenarios. There is a performance cost to each jQuery object created and jQuery wrapper methods for native JavaScript operations. Avoid creating jQuery objects wherever possible, especially in loops.
  • Optimize your loops. The fastest loops in JavaScript are reverse while loops and cached for loops. Avoid using jQuery loops (e.g., each()) wherever possible as there is a lot of overhead. In the case of jQuery objects, use .get() to get an array of DOM objects upon which reverse while and cached for loops can be used.
Reverse while:
var len = myArray.length, myArrayItem;
while (len--) {
	myArrayItem = myArray[len];
}

Cached for loop:

var i, len;
for (i = 0, len = myArray.length; i < len; i += 1) {
	myArrayItem = myArray[i];
}
  • Use if/else if/else instead of switch/case. Browsers tend to be faster at executing if/else if/else statements in comparison to switch/case statements so avoid using switch/case where possible.
  • Cache DOM elements, jQuery objects and object/array values. There is a lot of overhead to performing DOM searches, creating jQuery objects, and retrieving object/array values. Minimize the impact by caching the results where those results will be used more than once. It is best to store those results in local variables and reuse those variables.
  • Minimize reflow. Every change you make to the DOM has a significant performance cost as it causes page reflow. Minimize this cost by doing all the changes in a single operation to trigger reflow only once versus multiple operations which trigger reflow multiple times. This can be done in the following ways:
    • Put all the changes in a string or object and then append it to the DOM or replace part of the DOM with that string or object.
    • Detach an element from the DOM, make the changes to it, then reattach it to the DOM.
  • Avoid global DOM searches. The performance cost is much greater when searching the whole DOM rather than searching only a small part of it. If you already have a cached search, then take advantage of it and search from that point rather than searching the whole DOM again. For instance if you already have the search for the .button class already cached in the variable $buttons, then do $buttons.find('a.mybutton') to find the a elements versus $('a.mybutton'). Where possible, use native JavaScript for searching such as getElementById and getElementByTagName.
  • Optimized DOM searches first, filtering later. The fastest DOM searches in JavaScript are by id and tag name because of the native JavaScript function getElementById and getElementByTagName. Take advantage of this performance by doing optimized searches first then filtering later. For instance, instead of .find('a[href=*"url_fragment"]') do .find('a').filter('[href=*"url_fragment"]).

Testing your optimizations

To test your optimization changes, wrap a block of code with the following two lines of code.

var test=(new Date()).getTime();
//Code to test
console.log((new Date()).getTime() - test);

Additional techniques

CSS code optimization

  • Minimize class names. CSS class names are often reused multiple times within CSS and HTML files so can quickly add bulk to files if they are unnecessarily long. Keep class names as short as possible while ensuring they remain unique. A recent WET core framework class name shortening exercise resulted in a 10% to 30% decrease in file sizes.

Additional techniqus

HTML code optimization

  • Minimize the use of HTML comments. Every kilobyte counts when it comes to mobile devices so avoid unnecessarily bloating your code with HTML comments. Keep comments to the bare minimum by eliminating unnecessary comments and shortening the rest.
  • Remove commented out code. Commented out code should not be left in production Web pages. Commented out code can easily add many unnecessary kilobytes to downloads. Keep unused code separate from production Web pages.
  • Use tabs instead of spaces to indent code. It can take an average of 5 space characters to equal the indent of 1 tab character. Significant file size savings can be achieved by using tabs instead of spaces. Many editing tools provide the ability to quickly switch to indenting with tabs.
  • Minimize indenting. Indenting is helpful for code clarity but can quickly add to the HTML file size. Find a good balance between code clarity and file size to minimize the impact on the end user.
  • Remove the type attribute from script elements. In HTML5, type="text/javascript" is no longer required on script elements. Only use the type attribute on script elements for non-JavaScript scenarios.
  • Remove the type attribute from style elements. In HTML5, type="text/css" is no longer required on style elements. Only use the type attribute on style elements for non-CSS scenarios.

Web server optimization

  • Enable Gzip compression on your Web server. Gzip compression can reduce file transfer sizes by up to 70%. Note: Gzip compression does not reduce the impact on end user cache sizes (cached uncompressed) so files sizes should be reduced as much as possible before Gzip compression.

Optimization status of WET components

Component Average execution time (ms)
August 26, 2012 September 26, 2012 October 23, 2012 % Change
Since last month Sunce Aug 26, 2012
Accessible footnotes n/a 5 4 -20.0% -20.0%
Archived 2.5 2.5 2 -20.0% -20.0%
Calendar (dependency) 35 35 49 +40.0% +40.0%
Charts 131 (126, 2, 1, 1, 1) 807 (141, 89, 163, 414) 949(161, 121, 172, 495) +17.6% +624.4%
Charts (complex) 213 (206, 3, 1, 0, 1, 1, 1) 1682 (229, 182, 155, 157, 176, 188, 595) 1967 (261, 202, 194, 182, 207, 215, 706) +16.9% +823.5%
Core framework (incl. dependencies) 205.5 184 131 -28.8% -36.3%
Core framework (mobile, incl. dependencies) 611.5 575 1179 +105.0% (now preloads menu contents) +92.8% (now preloads menu contents)
Datepicker 151 (89, 62) 143 (85, 58) 137 (68, 69) -4.2% -9.3%
Event calendar 249 (84.5, 79.5, 85) 237 (81, 74.5, 81.5) 242 (78, 78, 86) +2.1% -2.8%
Feedback form 18 18 5 -72.2% -72.2%
Form validation 9.5 7 9.5 +26.3% 0%
Lightbox 23 (17, 3, 3) 23 (18, 3, 2) 23 (17, 3, 3) 0% 0%
Menu bar 50.5 62.5 54 -16.8% +6.9%
Multimedia player 85.5 (27, 18.5, 40) 81 (34, 18, 29) 89 (35, 23, 31) +9.9% +4.1%
Prettify 24.5 124 124 0% +120.7%
Progress (IE9) 2 (1, 1, 0) 2 (1, 1, 0) 2 (1, 1, 0) 0% 0%
Session timeout n/a 4 4 0% 0%
Share widget 46.5 29 27 -6.9% -41.9%
Slide out tab 15.5 19.5 9 -53.8% -41.9%
Slider (4 sliders) 10.5 21 21 0% +100%
Tabs 219 (26, 20, 36, 34, 30, 25, 15, 33) 219 (26, 20, 36, 34, 30, 25, 15, 33) 244 (24, 19, 36, 34, 29, 23, 33, 16, 30) +11.4% (new example added) +11.4% (new example added)
Tabs (mobile) 338 (49, 42, 36.5, 37.5, 49, 48.5, 37.5, 38) 48 (10, 7, 6, 6, 5, 5, 3, 6) 45 (6, 6, 5, 6, 4, 4, 5, 3, 6) -6.25% (new example added) -86.7% (new example added)
Text highlighting 4 4 4 0% 0%
Web feeds widget 13 (4.5, 4.5, 4) 13 (5, 4, 4) 13 (5, 4, 4) 0% 0%
Zebra striping 51 (1, 15, 1, 9, 6.5, 7.5, 2, 1.5, 2, 1, 4.5) 56 (19, 10, 9, 8, 2, 2, 1, 1, 4) 35 (10, 5, 5, 4, 1, 2, 2, 1, 5) -37.5% -31.4%

Component execution times averaged over two runs (in brackets mean multiple calls in the same run)

  • Note 1: All run locally using Firefox 16
  • Note 2: Excludes loading of dependencies (or any theme-based preparatory work)
  • Note 3: Used following code to determine timing:
var test = (new Date()).getTime();
console.log((new Date()).getTime() - test);
⚠️ **GitHub.com Fallback** ⚠️