开发者

Does caching jQuery objects in an array improve speed?

Today I was making an effect for share-icons using jQuery. The effect is a bit complicated so I tried to think of a way to optimize preformance. I ended up caching the $(this) object into array.

Effect Demo

I uploaded a working example of the effect using the array-cached objects (Hover on the icons to see the effect): http://mahersalam.co.cc/addthis/

HTML:

<div id="share-widget" class="addthis_toolbox">
    <a class="addthis_button_favorites" title="أضف للمفضلة"><div>أضف للمفضلة</div></a>
    <a class="addthis_button_facebook" title="شارك في فيسبوك"><div>شارك في فيسبوك</div></a>
    <a class="addthis_button_twitter" title="شارك في تويتر"><div>شارك في تويتر</div></a>
    <a class="addthis_button_email" title="أرسل الصفحة بالإيميل"><div>أرسل الصفحة بالإيميل</div></a>
    <a class="addthis_button_compact" title="أضغط هنا لمشاهدة المزيد من خدمات المشاركة"><div>المزيد من الخدمات</div></a>
</div>

Javascript:

// Return jQuery-obj of the share links
var shareLinks = $('#share-widget').find('a').css('opacity', 0.8);

//////////////////////////////////////////
// Only jQuery way
//////////////////////////////////////////

shareLinks.hover( 
    function () {
        $(this).clearQueue()
            .siblings()
                .stop(true,false).fadeTo('fast', 0.3)
            .end()
                .stop(true, true).fadeTo('normal', 1);
    },
    function () {
        shareLinks.delay(100).fadeTo('normal', 0.8);
})


//////////////////////////////////////////
// jQuery + Array cache way
////////////////////////////////////////// 

// Cache the array
var linksArr = [];

$.each( shareLinks, function (i) {

    linksArr.push( $(this) );

    linksArr[i].hover( function () {
        linksArr[i].clearQueue()
                    .siblings()
                        .stop(true,false).fadeTo('fast', 0.3)
                    .end()
                        .stop(true, true).fadeTo('normal', 1);
     },
    function () {
        shareLinks.delay(100).fadeTo('normal', 开发者_开发百科0.8);
    })
});

I just want to know if the array cached objects will make the performance faster or is it just not necessary. Also if anyone have a better idea to make this effect, I'm all ears ^^.


In this case it is not necessary. It is even more difficult to understand imo and maybe even slower. In your code:

shareLinks.hover( 
    function () {
        $(this).clearQueue()
            .siblings()
                .stop(true,false).fadeTo('fast', 0.3)
            .end()
                .stop(true, true).fadeTo('normal', 1);
    },
    function () {
        shareLinks.delay(100).fadeTo('normal', 0.8);
});

you are accessing $(this) only once anyway, why do you want to cache it? Afaik, $(this) is cheap anyway as it does not cause a search in the DOM.


It is only of advantage if you are evaluating the same selector several times (e.g. in a loop):

for(...) { 
   $('#share-widget div ul li > a').something(i);
}

is better written as

var $elements = $('#share-widget div ul li > a');
for(...) { 
   $elements.something(i);
}

Update:

Regarding what happens if you call $(this), this is the corresponding part from the code:

// Handle $(DOMElement)
if ( selector.nodeType ) {
    this.context = this[0] = selector;
    this.length = 1;
     return this;
}

and this is almost the at the top of the function. So it is really not doing much.


The only caching I see going on is when you use this line

var shareLinks = $('#share-widget').find('a').css('opacity', 0.8);

which could perhaps be made faster by combining the (but I doubt it, and it's a single selector, so not that much to worry about here)

var shareLinks = $('#share-widget a').css('opacity', 0.8);

Everything else I see isn't really caching. Ergo I'm gonna put in my $0.05 and tell you to make it readable first and foremost, because readable code is maintainable code. Everything else is fluff for your ego.


One way to improve performance, especially if you have a lot of links, is to use JQuery's .delegate() function:

$('#share-widget').delegate('a', 'mouseenter', function() {
    $(this).clearQueue()
        .siblings()
            .stop(true,false)
            .fadeTo('fast', 0.3)
        .end()
            .stop(true, true)
            .fadeTo('normal', 1);
});
$('#share-widget').delegate('a', 'mouseleave', function() {
    shareLinks.delay(100)
        .fadeTo('normal', 0.8);
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜