Tell me more ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

My application hangs up on IE and mobile browsers when these functions are fired. Is there anything that stands out as being obviously performance-killing?

$this.find('input.bundle-check').live('change', function() {
    var $box = $(this),
    ntn = $box.data().ntn,
    price = $box.data().price,
    savings = $box.data().savings;
    if ($box.is(':checked')) {
        productsBundled[ntn] = {
            "price"     :   price,
            "savings"   :   savings,
            "ntnid"     :   ntn,
            "qty"       :   1
        }; 
        $box.siblings('label').text(' Selected')
        $box.closest('.grid-product').fadeTo(300, 0.5)
    } else {
        $box.siblings('label').text(' Add Item');
        delete productsBundled[ntn];
        $box.closest('.grid-product').fadeTo(300, 1.0)
    }
    refreshSelectedItems(productsBundled);
    $this.find('.itemCount').text(concat('(',objectCount(productsBundled),')'));

})

function refreshSelectedItems(products, remote) {
    var itemntns = [], totalPrice=0.00, totalSavings=0.00;
    products = products || {};
    remote = remote || 2;
    if (objectCount(products) > 0) {
        $.each(products, function(i, item) {
            $qtyBox = $('.selected-item[data-ntn=' + i + '] .cartqty');
            itemntns.push(i);
            totalPrice += (item.price * ($qtyBox.val() || 1));
            totalSavings += (item.savings * ($qtyBox.val() || 1));
                    // console.log('qtyBox', $qtyBox.val())
                }); 

        if(remote > 1) {
            $.ajax({
                url: '/Includes/pageHelper.cfc',
                type: 'post',
                async: true,
                data: {
                    method: "getBundleSelectedItems",
                    productList: itemntns.join(',')
                },
                success: function(data) {
                    var $container = $('.selected-items > span');
                    $container.html(data);
                    $.each($container.find('.selected-item'), function() {
                        var myntn = $(this).data().ntn,
                        $price = $(this).find('.price'),
                        $bunPrice = $('<span />').addClass('bundle-price');

                        $(this).find('.cartqty').val(productsBundled[myntn].qty);

                        if (productsBundled[myntn].savings > 0) {
                            $bunPrice.text(concat(' $', productsBundled[myntn].price.toFixed(2)));
                            $(this).find('em').hide();
                            $price.after($bunPrice.after($('<span />').addClass('sale').text(concat(' You save $', productsBundled[myntn].savings.toFixed(2), '!'))));
                        }
                    })
                }
            })
        }
    } else {
        $('.selected-items > span').html('');
    }

    $this.find('.bundle-saving').text(concat("$", totalSavings.toFixed(2)));
    $this.find('.bundle-addons').text(concat("$", totalPrice.toFixed(2)));
    totalPrice = totalPrice + (parseFloat($('.original-products > div:has(:checked)').data().price) * parseInt($('.original-products > div:has(:checked) .cartqty').val()));
    $this.find('.bundle-total').text(concat("$", totalPrice.toFixed(2)));

}
share|improve this question
well... live() should no longer be used.. it is deprecated. In newer versions use .on() and in older versions use .delegate() - not sure if this will impact performance that much, but .live() is known to be slow. – rlemon Aug 15 '12 at 14:44
I typically use on, but this content can be loaded with AJAX. maybe this was too much of a shortcut to simply rebinding? – Kyle Macey Aug 15 '12 at 14:47
@KyleMacey If the content can be added after the handler is attached, then bind to a parent element [that is always there] and provide the selector of the children to bind the handler to: $this.on('click', 'input.bundle-check', handler); . The API explains this. – ANeves Aug 15 '12 at 15:31
I always wondered what the advantage was of that syntax... thanks – Kyle Macey Aug 15 '12 at 15:32
it would probably be quicker to use a for() loop instead of $.each(products, function(i, item) { – Zathrus Writer Aug 16 '12 at 6:50

1 Answer

up vote 1 down vote accepted

There are a few things which stand out to me:

var $box = $(this),
ntn = $box.data().ntn,
price = $box.data().price,
savings = $box.data().savings;

You use $box.data() several times; it may be faster to cache the return value of that function.

if ($box.is(':checked')) {

:checked is not a standard CSS selector, so it will be slower than simply:

if (this.checked) {

Later, you used

                $.each($container.find('.selected-item'), function() {

I'm not sure if it's faster, but you could just do:

                $container.find('.selected-item').each(function() {

Finally, this line:

totalPrice = totalPrice + (parseFloat($('.original-products > div:has(:checked)').data().price) * parseInt($('.original-products > div:has(:checked) .cartqty').val()));

The :has selector is not standard CSS, so it can't use browsers' native functions. instead, consider using the has() method instead:

totalPrice = totalPrice + (parseFloat($('.original-products').children('div').has(':checked').data().price) * parseInt($('.original-products').children('div').has(':checked').find('.cartqty').val(), 10));

Note that I also added the radix argument to parseInt. A micro-optimization at best, but it does mean the JS engine doesn't need to guess.

Hope that helps.

share|improve this answer
Thank you, actually made a significant difference in IE – Kyle Macey Aug 15 '12 at 17:22

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.