Efficiency of this constantly running time processor for an HTML5 video control bar I built a custom HTML5 video control bar, and for each second, it updates two readings:


Time Elapsed
Time Remaining


in hh:mm:ss notation, like so:



Because of how often this function runs, I want it to be as efficient as possible.

I created this JS Fiddle to test benchmarks. It runs the timer normally, until you un-comment the benchmark and comment the casual running func. The commented function call runs this function 1,000,000 times and logs the speed via the console's timing utility.

I'm looking for best practices, efficiency, and general improvements.



Here's the code. For testing, it's been modified to run in a loop or at a set interval rather than being connected to a video.

/* Video Time Processing Benchmark Snippet */

var timeProgress = $("#time-progress"),
    timeRemaining = $("#time-remaining");

// Set mock video duration for testing
var duration = 5000;

// Convert numbers to double+ digit format (09, 99, 999)
function digitize(n) {
    return n &gt; 9 ? "" + n : "0" + n;
}

// Convert seconds to hh:mm:ss
function secondsToHMS(seconds) {
    var numhours = digitize(Math.floor(((seconds % 31536000) % 86400) / 3600));
    var numminutes = digitize(Math.floor((((seconds % 31536000) % 86400) % 3600) / 60));
    var numseconds = digitize(Math.floor((((seconds % 31536000) % 86400) % 3600) % 60));
    return numhours + ":" + numminutes + ":" + numseconds;
}

// Process the elapsed and remaining times to two hh:mm:ss format
function processTime(currentTime) {
    var value = (100 / duration) * currentTime;
    var progressHMS = secondsToHMS(currentTime);
    var remainingHMS = "-" + secondsToHMS(duration - currentTime);
    timeProgress.html(progressHMS);
    timeRemaining.html(remainingHMS);
}

// Test time via interval or loop
function testTime(type, number) {
    if (type == "interval") {

        // If a number isn't provided, the default is every second (1000)
        if (!number) var number = 1000;
        var i = 0;

        // Set interval to run function
        setInterval(function(){
            currentTime = i;
            processTime(currentTime);
            i++;

            // Clear the interval when duration is reached
            if (i &gt; duration) clearInterval(Int);
        }, number);
    }
    else if (type == "loop"){
        for (var i = 0; i &lt; duration; i++){
            currentTime = i;
            processTime(currentTime);
        }
    }
}

// Use Int to set time for clearInterval() targetng
var Int = testTime("interval");

//Get benchamark on functon, vs optimized versions
/*
console.time("Benchmark");
    testTime("loop", 1000000);
console.timeEnd("Benchmark");
*/
If you're worried about performance, this should raise a red flag:

someJQueryObject = $("#some-id");
...
someJQueryObject.html(aPlainOldString);


.html(foo) is almost certainly slower than .innerHTML = foo, because .html() does a bunch of extra stuff, like checking if it can use innerHTML, trying to use innerHTML, catching errors if that fails and using a fallback, etc. Also, using innerHTML is probably slower than simply creating a Text node and updating its data property.

I'd suggest replacing timeProgress = $("#time-progress") with something like this:

var timeProgress = document.createTextNode('');

document.getElementById('time-progress').appendChild(timeProgress);


And replacing timeProgress.html(progressHMS); with this:

timeProgress.data = progressHMS;


This will be a significant performance improvement and will also eliminate the jQuery dependency. Using a large GP library like jQuery to select two elements and update their text content seems like overkill anyway.

Here's a jsPerf demonstrating the performance difference.