I've a code which applies marquee to certain elements by using the `requestAnimFrame` method. However, when I test my application on a lower spec PC (Intel Celeron 2.13GHz dou core) the CPU usage is skyrocketing and gets to a **minimum** of around 80%! (I have to mentioned that I have 2 elements that the custom maruqee is applied to). 

Also, there are cases where even 3 or 4 elements are being targeted by the marquee. There is also a case in my application, not so common, that there is another animation that scrolls text from the right to the left.

My development environment is a lot different, I'm using a 3.8GHz 8-cores CPU with a strong GPU so my CPU usage is no more than 11%. 

I'm not sure if it matters but locally I'm using xampp and on the tested PC I've been using wamp.

The code for my marquee is splitted into few functions:

    /**
     * Applies the marquee function to the elements who are overflowing
     */
    function tryMarquee(/**/) {
    
        var args = arguments;
    
        for(var i=0; i<args.length; i++) {
            var elem = $(args[i]);
            var containerHeight = elem.outerHeight(true);
            var contentHeight = calculateContentHeight(elem);
    
            // extract args
            var settings = $('.marqueeSettings');
            var speed = settings.find('input[data-target="'+args[i]+'"]input[name=marqueeSpeed]').val() || 1;
            var spacer = settings.find('input[data-target="'+args[i]+'"]input[name=marqueeSpacer]').val() == "1";
            var spacerHeight = settings.find('input[data-target="'+args[i]+'"]input[name=marqueeSpacerHeight]').val() || 60;
    
            if(contentHeight > containerHeight && containerHeight > 10) {
                marquee(args[i], speed, spacer, spacerHeight);
            }
    
        }
    
    }

    /**
     * Calculates the content height of an element by it's children's height
     * @param elem
     * @returns {number}
     */
    function calculateContentHeight(elem) {
    
        var total = 0;
        elem.children().not('.clone').each(function() {
            if(parseInt($(this).css('margin-top')) >= 0)
                total += $(this).height() + parseInt($(this).css('margin-top'));
            else
                total += $(this).height();
        });
    
        total -= 10;
        return total;
    
    }

    /**
     * Generates a spacer.
     * @param marginTop
     * @param height
     * @returns {*|jQuery|HTMLElement}
     */
    function generateSpacer(marginTop, height) {
    
        var spacer = $('<div class="marquee-spacer clone" style="margin-top: '+marginTop+'px;"></div>');
    
        height = height || 60;
    
        spacer.css({
            height: height
        });
    
        return spacer;
    
    }
    
    /**
     * returns a clone of an element's children
     * @param elem
     * @returns {*|jQuery|HTMLElement}
     */
    function duplicateContent(elem) {
        return elem.children().clone().addClass('clone');
    }
    /**
     * Checks the prayers element still needs the marquee.
     * @returns {boolean}
     */
    function keepPrayersMaruqee() {
    
        var containerHeight = elem.outerHeight(true);
        var contentHeight = calculateContentHeight(prayers);
    
        return contentHeight > containerHeight;
    
    }

These functions are only triggered once so I'm not sure if it has something to do when the application is fully loaded and already running.

    function marquee(className, scrollAmount, spacer, spacerHeight) {
    
        // parse spacer
        spacer = spacer || false;
    
        // select the elements
        var elemSet = $(className);
    
        // loop through the element set
        elemSet.each(function() {
    
            var $this = $(this);
    
            $this.addClass('marquee');
    
            /**
             *  TODO: if the container is taller than the content we should clone the content so there's no gap in the loop
             */
    
            var initialMargin = parseInt($this.find("div").first().css('margin-top'));
    
            if(spacer)
                $this.append(generateSpacer($this, initialMargin, spacerHeight));
    
            $this.append(duplicateContent($this));
    
            (function loop(){
    
                /**
                 *  This block of code is only executed on a certain element so check if it still needs to be scrolled
                 *  because there is a possibility that the element's children will be removed dynamically.
                 */
                if($this.hasClass('prayers'))
                    if( ! keepPrayersMaruqee()) {
                        // remove clone elements
                        $this.children('.clone').remove();
                        // cancel the maruqee
                        return;
                    }
    
    
                var first = $this.find("div").first();
                var top = parseInt(first.css('margin-top'));
                var height = first.outerHeight();
    
                if ((height+top) > 0){
                    first.css('margin-top','-='+scrollAmount);
                } else {
                    first.appendTo($this);
                    first.css('margin-top',initialMargin);
                }
    
                /**
                 * repeat the animation
                 * @see window.requestAnimFrame
                 */
                requestAnimFrame(loop);
            })();
    
        });
    }

[**A working fiddle**][1]

This is where the magic happens. I was trying to make this code as efficient as possible. Any suggestion on how I can actually improve this code and make it consume much less CPU power?


  [1]: http://jsfiddle.net/w0ebpp67/2/