I've got an existing single page web application of which I can't change the code. Some users complain that the application is not performing very well.
I would like to monitor the loading time in this way:
Record the time stamp of a click on the page
Record the time stamp of when the rendering of the page has been completed, after ajax requests and some other javascript magic has been done
Calculate the difference between the two time stamps and post it back to the server.
I can easily do step 1 and 3 with jQuery, however I'm not sure what's the best way to approach step 2?
As this seems to be a quite obvious scenario, is there a standard tool set to perform this kind of monitoring?
This helps:
function onLoad() {
var now = new Date().getTime();
var page_load_time = now - performance.timing.navigationStart;
console.log("User-perceived page loading time: " + page_load_time);
}
You could use the global ajaxStop event jQuery offers.
var start = +(new Date());
$(document).ajaxStop(function() {
var diff = +(new Date()) - start;
// do logging
});
This won't include the code executed after the last AJAX call, but if things happening before the last call contain the expected bottleneck, then this will be quite useful.
this can be achieved in following way...
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="jquery.min.js"></script>
<script type="text/javascript">
var startTime, endTime, timeDifference;
function doIt() {
var startTime = new Date().getTime();
$.ajax({
type: 'post',
url: 'a.php',
success: function (resp) {
endTime = new Date().getTime();
timeDifference = endTime - startTime; //Time Difference is stored in milliseconds
}
})
}
</script>
</head>
<body>
<button style="position: absolute; top:60px" onclick="doIt()">start</button>
</body>
</html>
It's not a perfect solution, however the following code is working. It start the timer when a user clicks. The checkHTML function monitors the changes in the page content.
var timeLogging = new Array();
var timeStart;
$(document).click(function() {
initLogEvent();
});
function initLogEvent() {
caption = $(".v-captiontext:first").text();
timeStart = +(new Date());
timeLogging.push(new Array(0,0));
timeLogging[timeLogging.length - 1][0] = timeStart;
}
initLogEvent();
// Start a timer to check the changes in html
window.setInterval(checkHtml, 250);
// Start a timer to create the reports
window.setInterval(sendReport, 1000);
var html;
function checkHtml() {
current = $("body").html();
if (current != html) {
html = current;
var diff = +(new Date()) - timeStart;
timeLogging[timeLogging.length - 1][1] = diff;
}
}
function sendReport() {
if (timeLogging.length > 3) {
console.log(timeLogging);
// Do additional stuff with the collected data
for (i = 0; i <= timeLogging.length; i++) {
timeLogging.shift();
}
}
}
Are you keeping all you application's markup in the page, even when it is hidden? If so you are probably choking the browser's memory. I recommend learning to offload your markup in localStorage like Bing and Google pioneers a few years ago. I wrote a blog about it the day I discovered the technique and I have used it ever since.
http://love2dev.com/#!article/Use-Local-Storage-to-Make-Your-Single-Page-Web-Application-Rock
Related
I'm trying to write a script that will allow me to redirect to a web page every Friday at a specific time.
Was hoping to have the script redirect to an Iframe for a live video feed, and after an hour, have the script also redirect to a html file that will be stored on the pc running a splash page till the next feed the following week, which will start the script again based on day and time.
Been trying for the past 3 hours to salvage something from scripts I've found on stack overflow with no success. Would GREATLY appreciate some help on this!
I Hope this will works for You.
function myFunction() {
var d = new Date();
var n = d.getDay()
var time=.getHours()
if(n==5)
{
//based on time
if(time==14)
{
window.location.href="www.YourRedirectpage.com";
}
}
This should work (ES5 syntax):
Date.prototype.hour = function () {return (this.getHours())}
Date.prototype.day = function () {return (this.getDay())}
var today = new Date()
if (today.hour() == "10" && today.day() == "6") {
// change you url here, such as; location.href ="friday url";
}
else {
// keep (or re-attribute) your base url, such as; location.href ="base url";
}
I guess you want some kind of simplified job in UI which will keep watching and do redirect for you and you don't need to manually intervene much. You should use a setTimeout from Javascript to achieve this.
What this solution does that it calculates the millisecond difference between coming Friday with specific time till current date time and starts a timeout event.
Hope this is easy to understands and helps you.
GIT Repo: https://github.com/helloritesh000/how-to-redirect-browser-at-specific-date-and-time
<!DOCTYPE html>
<html>
<body onload="RedirectTo(5, 15, 49, 30);"> <!-- RedirectTo(day(1-7(Monday)-(Sunday)),1-24 hour,1-60 min,1-60 sec) -->
<h1>This will reload redirect page</h1>
# - <p id="demo"></p>
<script>
function getNextDayOfWeek(date, dayOfWeek) {
// Code to check that date and dayOfWeek are valid left as an exercise ;)
var resultDate = new Date(date.getTime());
resultDate.setDate(date.getDate() + (7 + dayOfWeek - date.getDay()) % 7);
return resultDate;
}
function RedirectTo(day, hour, min, sec) {
var d = new Date(getNextDayOfWeek(new Date(), day));
d.setHours(hour);
d.setMinutes(min);
d.setSeconds(sec);
document.getElementById("demo").innerHTML = d;
var totalMilliSecDiff = d-new Date();
if(totalMilliSecDiff > 0)
{
setTimeout(function(){ window.location.href = "http://www.google.com"; }, totalMilliSecDiff);
}
}
</script>
</body>
</html>
I am trying to code for a test get people's tap frequency with music.
Here is something without the music, but people can tap on their laptop touch pad to get the data. However, the data seems not accurate enough, for example it at least be 200 milliseconds. and when we steady tap it, it offered a quite variable result. someone can tell me how to improve it?
Here is my code:
<!DOCTYPE html>
<html onclick="myFunction()">
<head>
<link rel="stylesheet" type="text/css" href="main.css">
<title>Click</title>
</head>
<body>
<script>
function myFunction() {
inner = document.getElementById("time").innerHTML;
if(inner === ""){
document.getElementById("time").innerHTML = Date();
}
else{
var curr = new Date();
console.log(curr);
var past = new Date(inner);
console.log(inner);
console.log(past);
var gap = curr.getTime() - past.getTime();
console.log(gap);
document.getElementById("time").innerHTML = curr;
var gapText = document.getElementById("gap").innerHTML;
gapText = gapText + gap + "<br>";
document.getElementById("gap").innerHTML = gapText;
}
}
</script>
<div><text>The current time is </text><text id="time"></text></div>
<div><text>The tap durations are (milliseconds):</text></div>
<div><text id="gap"></text></div>
</body>
</html>
I also got a large variable of time differences with your code on a MacBook Pro running in Chrome. Then I refactored your code and got significantly better performance, generally within ~30ms. Matthew Herbst is right, hardware is going to play a factor, but I think there are ways to improve performance. My refactored code is below, but a couple of observations:
Take out all the console.logs. They don't affect performance too much, but when you're worried about a handful of milliseconds, they do.
Only interact with the DOM when you absolutely have to. For instance, you're going to the DOM to get the last timestamp, in order to calculate the current value. Save it in a variable, it's faster.
Here's my code, let me know how well it works for you. Hope this helps.
<!DOCTYPE html>
<html onclick="myFunction()">
<head>
<link rel="stylesheet" type="text/css" href="main.css">
<title>Click</title>
</head>
<body>
<script>
var newTime;
function myFunction() {
if (newTime === undefined){
newTime = new Date();
// This will only run once
document.getElementById("time").innerHTML = newTime;
}
else{
// Here I'm not getting values from the DOM. I'm saving the value as a variable.
var oldTime = newTime;
newTime = new Date();
var gap = newTime.getTime() - oldTime.getTime();
var gapText = gap + "<br>";
document.getElementById("gap").innerHTML = gapText;
}
}
</script>
<div><text>The current time is </text><text id="time"></text></div>
<div><text>The tap durations are (milliseconds):</text></div>
<div><text id="gap"></text></div>
</body>
</html>
I have a form with 2 fields: date field #datefromtoday and number of days #daysfromtoday. I use a javascript function to:
1) Automatically listen to the datefromtoday and (if there is a date) display the number of days from today when the page is loaded
2) adjust the date from today when entering/modify the number of days.
Here is the code:
$(document).ready(function (){
function modifyDays(){ //definy function to modify days
var endDateToDays = $( "#datefromtoday" ).val();
var endDateToDays_obj = new Date(endDateToDays); // convert in object
var endDateToDays_ms = endDateToDays_obj.getTime(); // convert in ms
var todayDate = new Date(); //
var todayDate_ms = todayDate.getTime(); //
var daysFromToday = parseInt(Math.ceil( (endDateToDays_ms - todayDate_ms) / 1000 / 60 / 60 / 24 ) ) || ''; //if not number display nothing
document.getElementById("daysfromtoday").value = daysFromToday; //outuput
}
modifyDays(); //here is the problem. If I delete this line of code, everything works perfectly
$("#datefromtoday").on('change', function(){ //run function when modify delay date
modifyDays();
});
});
PROBLEM
the modifyDays function works like a charm on the on.change event, but
when is loaded on document ready, it interferes with datatables www.datatables.net and also with other scripts, and they don't work anymore...
I'm probably using the wrong code to call the function on page load.... any ideas? Thanks for your help!!!
If you think it is because of calling the main function, in the body element of the html page, add an onload attribute:
<body onload="loaded()">
and declare loaded as that main function:
var loaded = function (){
function modifyDays(){ //definy function to modify days
var endDateToDays = $( "#datefromtoday" ).val();
var endDateToDays_obj = new Date(endDateToDays); // convert in object
var endDateToDays_ms = endDateToDays_obj.getTime(); // convert in ms
var todayDate = new Date(); //
var todayDate_ms = todayDate.getTime(); //
var daysFromToday = parseInt(Math.ceil( (endDateToDays_ms - todayDate_ms) / 1000 / 60 / 60 / 24 ) ) || ''; //if not number display nothing
document.getElementById("daysfromtoday").value = daysFromToday; //outuput
}
modifyDays(); //here is the problem. If I delete this line of code, everything works perfectly
$("#datefromtoday").on('change', function(){ //run function when modify delay date
modifyDays();
});
};
Then it should work if the problem is how the function is called.
I don't think the problem is because of you are calling the function on page load. The error might be coming from inside the function modifyDays. Only dependency I see is #datefromtoday and #daysfromtoday. Check whether those nodes are there when the function execute on dom ready event.
If the timing of the function call is the problem, you can put the modifyDays(); call in a window.setTimeout(modifyDays, 5000); or something of the sort to delay it until the other scripts finish loading, so this snippet doesn't interrupt or interfere with them. You may want to put a placeholder in the html for the seconds when it isn't loaded yet if this works.
I'm trying to gather either an event or custom variable tracking on the turn.js plugin through Google Analytics. Right now it's set up for a custom variable. I'm trying to track time on page turns. In the plugin there is an event handler called 'turned'. This is an event that runs when the page has been turned. I have my analytics set up here, but they are collecting to google incorrectly. Any help with this is appreciated. I have the JS event below:
when: {
turned: function(event, page, view) {
_gaq.push(['_setCustomVar', 1, 'Page Spread Scope 1', 'page spread ' + view, 1 ]);
_gaq.push(['_trackPageview']);
}
}
Not sure what exact data you want but I think it is something like this.
Just wrote it right now, so haven't fully tested it. I did debug it and it seems to work fine.
It should record the page+pagenumber and it should record the time on that page with the new _trackTiming method
For your page turn this snippet:
<script>
$('#magazine').turn().bind("click", function(event){
pagenumber = $('#magazine').turn('page');
myTimer();
});
</script>
And then this in your head somewhere.
<script>
var startTime = new Date().getTime();
function myTimer(event) {
var endTime = new Date().getTime();
var timeSpent = endTime - startTime;
var hourInMillis = 1000 * 60 * 60;
if (0 < timeSpent && timeSpent < hourInMillis) {
_gaq.push(['_trackTiming', 'page-timer', 'time-on-page', timeSpent, pagenumber, 1]);
_gaq.push(['_trackPageview', 'turnedpage-' +pagenumber]);
}
return this;
}
//wiremedia.nl
</script>
Thanks in advance for any help...
I'm trying to (1) generate a begin time and end time for a form, (2) find the difference between the two, and (3) add the difference to a new input.
Here's what I have so far:
Begin time
<input id="starttimeinput" name="starttimeinput" type="text" value="">
<script>
$("#starttime").click(function () {
var begintime = event.timeStamp;
$("#starttimeinput").val(begintime);
});
</script>
end time
<input id="endtimeinput" name="endtimeinput" type="text" value="">
<script>
$("#endtime").click(function () {
var endtime = event.timeStamp;
$("#endtimeinput").val(endtime);
});
</script>
<input id="totaltime" name="totaltime" type="text">
<script>
$("#totaltime").focus(function () {
var begintime = $("#starttimeinput").val();
var endtime = $("#endtimeinput").val();
var totaltime = endtime - begintime;
$("#totaltime").val(totaltime);
});
</script>
The first part works (entering the timestamps into the beginning time and end time inputs). I've never worked with numbers before and can't figure out the second part. The result that comes up is "NaN".
Also this might be useful to know the the time between when the links are clicked should be around 30 seconds...
Thanks much for any help you guys have answered so many questions of mine without me having to post!
You need to parseInt() the times back out, otherwise they're just strings (as returned by .val()).
$("#totaltime").focus(function () {
var begintime = parseInt($("#starttimeinput").val(), 10),
endtime = parseInt($("#endtimeinput").val(), 10),
totaltime = endtime - begintime;
$("#totaltime").val(totaltime);
});
Personally, I'd sooner just store the begintime and endtime values myself, rather than in text inputs (why does the user need to see them, anyway?). Like this:
var begintime,
endtime;
$("#starttime").click(function (event) {
begintime = event.timeStamp;
//$("#starttimeinput").val(begintime);
});
$("#endtime").click(function (event) {
endtime = event.timeStamp;
//$("#endtimeinput").val(endtime);
});
$("#totaltime").focus(function () {
$("#totaltime").val(endtime - begintime);
});
On a side note, I would recommend moving your jQuery code out of inline <script> tags and into an external JS file. This makes for more maintainable markup and JS. Just wrap all of your JS code in a document ready handler:
$(document).ready(function () {
/* your code here */
});
or, more concisely,
$(function () {
/* your code here */
});