I found an opportunity to make an optimization in one area of jQuery UI, which might be applicable to other areas as well. The basic idea is to minimize the number of calls to addClass(), since an arbitrary number of classes can be added with a single call.
Currently in
_resetButton() method of the button code (
https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.button.js), there is the potential to call
addClass() on
buttonElement multiple times. To optimize this, the
addClass() call should be defered, and the class names to add buffered in a string, until they can all be added together.
- if ( icons.primary || icons.secondary ) {
- buttonElement.addClass( "ui-button-text-icon" +
- ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
- if ( icons.primary ) {
- buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
- }
- if ( icons.secondary ) {
- buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
- }
- if ( !this.options.text ) {
- buttonElement
- .addClass( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" )
- .removeClass( "ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary" );
- if ( !this.hasTitle ) {
- buttonElement.attr( "title", buttonText );
- }
- }
- } ...
And the following test code demonstrates the difference that calling
addClass() fewer times can make, in IE 8:
- function getRunTime(fn) {
var startTime = new Date();
fn();
var endTime = new Date();
return endTime - startTime;
} - function runAddClassOptimizationTest() {
- var nIterations = 1000;
- var content = $('#content');
- var separateResult = getRunTime(function() {
- for (var i = 0; i < nIterations; ++i) {
- content[0].className = "";
- content.addClass('foo');
- content.addClass('bar');
- }
- });
- var combinedResult = getRunTime(function() {
- for (var i = 0; i < nIterations; ++i) {
- content[0].className = "";
- content.addClass('foo bar');
- }
- });
- alert('Separate Result: ' + separateResult
- + '\nCombined Result: ' + combinedResult);
- }
My results for IE 8:
Separate Result: 453
Combined Result: 250
Note that this technique might be applicable to many areas of the jQuery UI code!
Haw-Bin