jquery/jquery — pull request #1200 by orkel (2013-03-12 11:18:38+00:00)
Title: Fixes #10515 - Implementation of iAH

Based on @dmethvin idea.

By opening this PR, i want, one way or another, to close #10515, but i'm not sure what a resolution of that ticket should be.

Perf tests

jQuery.append

big HTML-string

small HTML-string

big HTML-string, hidden element

small HTML-string, hidden element

big HTML-string, disconnected element

small HTML-string, disconnected element

jQuery.prepend

big HTML-string

small HTML-string

big HTML-string, hidden element

small HTML-string, hidden element

big HTML-string, disconnected element

small HTML-string, disconnected element

jQuery.before

big HTML-string

small HTML-string

big HTML-string, hidden element

small HTML-string, hidden element

big HTML-string, disconnected element

small HTML-string, disconnected element

jQuery.after

big HTML-string

small HTML-string

big HTML-string, hidden element

small HTML-string, hidden element

big HTML-string, disconnected element

small HTML-string, disconnected element

What's the takeaway?

This is a difference between iAH methods and current DOM-manipulation tactics –

Conditions
Results

Big HTML-string, attached element
Small speed increase in almost all browsers, considerable speed decrease in WebKit

Small HTML-string, attached element
All browsers shown good speed increase

Big HTML-string, hidden element
Slightly better results

Small HTML-string, hidden element
All browsers shown good speed increase

jQuery#append/prepend, Big/small HTML-string, disconnected element
Either equal or slightly better results

jQuery#before/after, big HTML-string, disconnected element
Slightly better results for most cases, except Opera performed slightly worse

jQuery#before/after, small HTML-string, disconnected element
All browsers shown good speed increase

Perf hit

In some situations insertAdjacentHTML method could not be applied, guards for that cases will slow down jQuery#domManip method –

If first argument for iAH is either beforebegin or afterend (affect jQuery#before/after), insertAdjacentHTML could not be applied if target element does not have parent element (obviously) or that element is document fragment (less obvious), although iAH could be used if first argument is afterbegin or beforeend (jQuery#append/prepend) for such an element, but it would reguire additional check inside for loop. Perf hit for jQuery#append/prepend methods applied to parentless element would be:

jQuery#append – Big/small HTML-string

jQuery#prepend – Big/small HTML-string

HTML-string in IE9, could not be inserted to table element through insertAdjacentHTML method, plus in other browsers, that code path perform worse then current way. Perf hit for bypassing table element as target node would be – http://jsperf.com/iah-to-table/3

Sometimes HTML-string must be wrapped, like when creating tr element, in such case if insertAdjacentHTML is not applied to table element that code would silently fail, therefore for that cases iAH path must not be taken, perf hit will be the same as for above table example

iAH could not take object as an argument. Perf hit by circumventing object as an argument would be – http://jsperf.com/jq-iah-append-object

document fragment (and all other types of an node) does not have insertAdjacentHTML method, also script element should not be inserted that way. Perf hit for that cases would be – http://jsperf.com/jq-iah-append-to-documentfragment

As conclusion

Performance ratio of WebKit iAH in case of big HTML-string relative to current DOM-manipulation way is utterly depressing, one might even suggest that this happens due to regexp check, but it's not the case – in that version of a iAH implementation regexp check is removed, which does not heavily change the picture. Solution for that problem might be check size for HTML-string, use of jQuery#append as an example – Big/small HTML-string, this control would flatten disproportion in WebKit case, but it also decrease performance of other browsers.

I suppose big HTML-string is rarely acts as argument to jQuery's DOM-manipulation methods, maybe only in case when all page should be reflowed, besides, 184 operation per second might be fast enough for that task, ergo it might be more productive to dwell on more optimistic small HTML-string's cases, in respect that if whether or not iAH should be employed was made only by proceeding most of other samples then decision would be little more obvious? As of perf hit examples (see above) – some of them are rare edge cases, some of them do not matter that much and some of them aren't that conclusive.

But considering all that, i'd say this research is showed a lot of arguments to not use iAH inside of jQuery#domManip at all.