Preventing Countup Timer from Blocking UI in Mobile Web App
I have a count up timer in javascript which constantly updates the time on
the page every second. I also have a reset button, which upon being
clicked resets the timer and also performs a few other actions such as
incrementing a counter, saving the increased value of the counter and
saving the time when the timer was last reset in the local storage.
When I tap the reset button, though it performs the required actions,
sometimes it freezes the UI (the button remains in its pressed state and
the timer and count does not increase eventually, then after 5-6 seconds
it reverts back to normal). This typically happens when the timer is just
about to update the time.
I understand this has got something to do with the DOM manipulation by
javascript blocking the thread and thus queuing up the other functions. I
tried to resole this by adding a callback function to the reset button
action and setting time out to some of the other actions but it does not
seem to work.
Please note that this is for a mobile app, specifically target at mobile
safari and thus I cannot use 'onunload' or 'onbeforeunload'.
I am looking for a way in which tapping the reset button increases the
counter and resets the timer in a 'smooth' manner without providing any
lag or delay. Any help would be much appreciated.
My Code for the button click:
$("#js-reset-btn").click(function () {
// To clear the timeout on the timer
clearTimeout(Timer.displayTime)
// To reset the timer
Timer.resetTime();
// To increase the count
Counter.increaseCount();
// To temporarily ave the time
Timer.cacheTime();
// To defer the localstorage by a few moments
setTimeout(Timer.displayTime, 1000);
window.setTimeout(function() {
// Save the updated count
Counter.saveCount();
// Save the Time when timer was reset
Timer.saveTime();
}, 10);
});
The Code for the Timer and Counter Modules:
var Timer = (function () {
var timeText = $("#js-time-elapsed");
var storedTime = localStorage.getItem('storedTime');
return {
displayTime : function () {
var endTime = new Date();
var timeDiff = endTime - startTime;
timeDiff /= 1000;
var seconds = Math.round(timeDiff % 60);
seconds = zeroPad(seconds, 2);
timeDiff = Math.floor(timeDiff / 60);
var minutes = Math.round(timeDiff % 60);
minutes = zeroPad(minutes, 2);
timeDiff = Math.floor(timeDiff / 60);
var hours = Math.round(timeDiff % 24);
hours = zeroPad(hours, 2);
timeDiff = Math.floor(timeDiff / 24);
var days = timeDiff;
if (days < 1) {
timeText.text(hours+"h" + ":" + minutes+"m" + ":" + seconds+"s");
} else {
timeText.text(days+"d" + ":" + hours+"h" + ":" + minutes+"m");
}
setTimeout(Timer.displayTime, 1000);
},
updateTime : function () {
if (storedTime) {
startTime = new Date(storedTime);
setTimeout(Timer.displayTime, 1000);
}
},
resetTime : function () {
timeText.text("00h:00m:00s");
},
cacheTime : function () {
startTime = new Date();
},
saveTime : function () {
localStorage.setItem('storedTime', startTime);
}
};
})();
var Counter = (function () {
var countText = $("#js-count");
var storedCount = localStorage.getItem('storedCount');
var updatedCount;
return {
updateCount : function () {
if (storedCount) {
countText.text(storedCount);
} else {
countText.text("0");
}
},
resetCount: function () {
countText.text("0");
},
increaseCount : function () {
var i = countText.text();
i++;
updatedCount = i;
countText.text(updatedCount);
},
saveCount : function () {
localStorage.setItem('storedCount', updatedCount);
}
};
})();
I am considering trying out Web Workes for this but I read somewhere that
since this is mostly to do with the DOM manipulation, they wont help much.
Also I actually have not idea how to use them.
No comments:
Post a Comment