Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #10453 (new enhancement)

Opened 5 months ago

Last modified 5 months ago

[PATCH] Form.serialize performance improvement

Reported by: bwiart Assigned to: sam
Priority: normal Milestone: 2.x
Component: Prototype Version: edge
Severity: major Keywords: form serialization speed
Cc:

Description

When using Form.serialize on forms containing a lot of elements (input, select, etc..) the serialization speed on IE 6 is awful due to the use of Element.extend. Even if the elements have no name attribute the serialization speed is really low.

By using a specialised version of serialize which do not use Element.extend i was able to cut the execution time by 70% on big forms.

The improvement is less impressive on ff and safari but exists.

2 files attached to this ticket :

  • bigform.html which tests the new method vs the current one
  • form.js which contains 2 new method fastSerialize and _fastSerializeElements

Benoit WIART UBIK Ingénierie

fastSerialize: function(form, options) {
    return Form._fastSerializeElements($(form).getElementsByTagName('*'), options);
  },

_fastSerializeElements: function(elements, options) {
    if (typeof options != 'object') options = { hash: !!options };
    else if (Object.isUndefined(options.hash)) options.hash = true;
    var key, value, submitted = false, submit = options.submit;
    
    var result = {};
    for(var i=0, size=elements.length; i <size; i++) 
    {
	var element = elements[i];
	var name = element.name;
        if (!name)
        	continue;

        if (Form.Element.Serializers[element.tagName.toLowerCase()]) 
        { 
		if (!element.disabled) { 
			key = name, value = Form.Element.Serializers[element.tagName.toLowerCase()](element); 
			if (value != null && (element.type != 'submit' || (!submitted &&
            		submit !== false && (!submit || key == submit) && (submitted = true)))) { 
          			if (key in result) {
			            // a key is already present; construct an array of values
			            if (!Object.isArray(result[key])) result[key] = [result[key]];
			            result[key].push(value);
			          }
			          else result[key] = value;
        		} 
			} 
		} 
	} 
 
    return options.hash ? result : Object.toQueryString(result);
  }

Attachments

bigform.html (6.3 kB) - added by bwiart on 12/10/07 15:36:48.
form.js (10.5 kB) - added by bwiart on 12/10/07 15:37:49.
forms.js.diff (1.9 kB) - added by bwiart on 12/10/07 16:17:41.
diff file

Change History

12/10/07 15:36:48 changed by bwiart

  • attachment bigform.html added.

12/10/07 15:37:49 changed by bwiart

  • attachment form.js added.

12/10/07 16:17:41 changed by bwiart

  • attachment forms.js.diff added.

diff file

12/10/07 16:20:01 changed by bwiart

  • summary changed from Form.serialize performance improvement to [PATCH] Form.serialize performance improvement.

(in reply to: ↑ description ) 12/10/07 22:43:03 changed by bwiart

You can also improve this implementation by replacing

$(form).getElementsByTagName('*')

with the concatenation of

 $(form).getElementsByTagName('input') 
 $(form).getElementsByTagName('select') 
 $(form).getElementsByTagName('textarea') 

Benoit WIART