I've stumbled across jQuery.fly() - flyweight pattern performance benchmark and after looking at the testing code and the plugin code itself (also see below), I can't work out what use is it? I've searched the internet and cannot find any useful information about the plugin itself.
Is it a more efficient way of looping/iterating over an array rather than using $(this)
in .each
?
Iterate using jQuery object
a.each(function() { $(this); });
Iterate using jQuery.fly()
a.each(function() { $.fly(this); });
- almost 2x faster in Firefox 4.0.1
- almost 3x faster in Chrome 12
.fly
(function($) {
var fly = $(),
push = Array.prototype.push;
$.fly = function(elem) {
var len = fly.length,
i;
if ($.isArray(elem)) {
fly.length = 0;
i = push.apply(fly, elem);
} else {
if (elem instanceof $) {
return elem;
}
开发者_StackOverflow社区 if (typeof elem == "string") {
throw "use jQuery()";
}
fly[0] = elem;
fly.length = i = 1;
}
// remove orphaned references
while (i<len) {
delete fly[i++];
}
return fly;
};
})(jQuery);
Disclaimer: You get an instance of the global fly
that changes state every time you call $.fly
. If you store it in a variable it will break. This is a micro optimisation and should not be used unless properly benchmarked.
Optimisation: Any situation where you can justify using $.fly
because using $
is a bottleneck then the correct solution is to not use jQuery and do DOM manipulation in "vanilla JavaScript"
The idea is that calling jQuery
is expensive. To avoid this you call $()
once and then inject DOM nodes into it.
This basically has one global instance of jQuery and swaps out what DOM nodes live inside it.
Flyweight Pattern
A flyweight is an object that minimizes memory use by sharing as much data as possible with other similar objects
This is achieved by having only one jQuery object.
var len = fly.length,
i;
// if elem is array push all dom nodes into fly.
if ($.isArray(elem)) {
// empties fly
fly.length = 0;
i = push.apply(fly, elem);
} else {
// if already $ then return it
if (elem instanceof $) {
return elem;
}
// dont use selectors
if (typeof elem == "string") {
throw "use jQuery()";
}
// set dom node.
fly[0] = elem;
fly.length = i = 1;
}
// remove any elements further in the array.
while (i<len) {
delete fly[i++];
}
return fly;
Further Disclaimer: This code does not set this.context
, this.selector
so any code that uses that or any internal jQuery code that can be optimised by using those is not optimised.
You need thorough benchmarking and careful testing to be able to conclude that not setting those is worthy of the optimisation and that sharing one jQuery object does not cause subtle errors/side-effects in your code.
精彩评论