I'm working on a Javascript stopwatch application, and it works in every browser but Chrome.
Here is a fiddle:
http://jsfiddle.net/djwelsh/Sxyy8/
In theory it is very simple. Clicking the Start button records the epoch time in milliseconds, and starts a setInterval. On each interval, that starting epoch time is subtracted from the current epoch time. This leaves us with a value in milliseconds, which is converted to h:m:s:cs and displayed on the page.
The problem
My problem is with Chrome. Every time the timer reaches 10000 ms, the tab crashes with the "Aw, snap" message.
One bizarre aspect is that the crash still happens if you hit Stop, wait a few seconds, and then hit Start again. This would seem to indicate that it's a memory issue - something is filling up to the point where it cannot hold any more, and overflowing. But inspecting memory in both dev tools and the resource monitor shows nothing at all unusual.
Possible solutions
The problem can be averted by changing the interval value to a number larger than 100 ms (the default I want to use is 50). It can also be averted by logging the timer values in the console, for some reason.
The trouble is, unless I know why it is happening, I can't be confident that these quick-fixes are actually resolving the problem. I don't want to publish the page until I know it will work in all current browsers.
I know this seems like a fairly narrow-scope problem, but I'm hoping the solution will reveal something larger in scope that might help other people (an idiosyncrasy of Chrome's timer functions or something).
EDIT
By the way, I know that stopping and restarting the timer doesn't work the way it ought to in a real stopwatch; I haven't finished implementing that part yet. I thought it would be better to keep it as simple as possible for SO.
For reference (and great justice), here is the updated version. Still crashes at 10000:
http://jsfiddle.net/djwelsh/Sxyy8/7/
SOLUTION
Based on the answer from #Akhlesh, I updated the fiddle. It now runs properly and acts like a stopwatch: http://jsfiddle.net/djwelsh/Sxyy8/18/
In case you're wondering, I need to use the epoch-based technique (as opposed to just incrementing a base value) because sometimes memory usage issues cause the interval not to be called every second - if the tab is moved to the background while the timer is still running, for example.
You can avoid crashing of tab by making time and now variable as global instead of creating those variable again n again inside Update function.
var uTime,uNow;
//Update function will use same variable to initialize time and now
updateTime: function () {
uNow = Date.now();
oO.milliseconds = uNow - oO.epoch;
uTime = oO.getTimeObject(oO.milliseconds);
oO.el.testClock.text('' + uTime.h + ':' + uTime.m + ':' + uTime.s + ':' + uTime.ms + '');
}
Fiddle Demo
I am not sure about the reason but i think GC is not able to deallocate those variable and same time it allocating new variable and that is causing crash.
Related
my current work is basically clicking a button every couple of minutes and check if there are any new tickets.
With some programming background I thought this would be an easy-to-automate task, but being completely new to javascript, I'm already struggling with the "button clicking".
Unfortunately, because it is an internal website, I can't share the exact code, but I'll try to give as much information as I am able to.
I tried to "click" in the console:
'document.getElementById("IDofButton").click()'
But it gives me an error "undefined"; without the ".click()" at the end I get the correct element as a result. I tried it with "$" instead of document.getElementById, but even that didn't work, so I gave up on the idea of simply clicking the button, even though I think that's the easier way.
Debugging in chrome with breakpoints and the performance profiler, I could find the first called function "h()", it runs for 0.020 ms, then another function gets called, running for 0.012 ms and then a longer function gets called running for 14.8 ms, several others follow. My guess or better hope, was that the first two functions check something and then start the whole process. But I can't simply call any of the functions with like the following example syntax: "h()".
I'd be very glad, if anyone has an idea or could point me in the right direction.
Thank you very much.
EDIT/UPDATE:
I finally found the problem:
While debugging with the performance profiler I saw, that the functions are triggered by a mouseup event and I thought the "[...].click()" simulates a mousedown and a mouseup instead of a click.
I now copied a function simulating the whole mouseover>mousedown>mouseup>click and it works as expected.
Thank you to all who helped me with the whole situation!
You get undefined because your selector is wrong. Try learning css selectors and see if it helps you(https://www.w3schools.com/cssref/css_selectors.asp)
You can also inspect the elements in the dev tools and right clicking on the element, going to copy->Copy JS Path. This will give you the correct selector.
Also you can select the element and reference it in the dev tools console with $0.
Then if you want to re-click every second then use setInterval
setInterval(() => {
document.querySelector('#someId').click()
}, 1000)
Hope that helps you, good luck!
setInterval(
function(){
document.getElementById('IDofButton').click()
},5000)// time in milliseconds i set for 5 sec
Above time set for each 5 Seconds.
if doesn't work Let me know.
I experienced a little problem on Firefox the other day. I am writing code to measure performance of the web site that I'm working on.
For this test all I do is call new Date().toLocaleString() every 10 milliseconds and log the times it returns. The first time returned always seems to be a few milliseconds (or even seconds) AFTER the current time. Then the next measurements are always correct, it's only the first measurement that returns "future" time, then it seems to get itself together.
This only happens on starting up the browser. When I refresh the browser I don't see this happening.
I ran this on Chrome as well but there it seems to work.
Here are some times from the log I'm getting:
28/07/2017, 16:18:34
28/07/2017, 16:18:20
28/07/2017, 16:18:21
28/07/2017, 16:18:22
28/07/2017, 16:18:23
28/07/2017, 16:18:24
28/07/2017, 16:18:25
..etc
As you can see the first time is totally off, it's 14 seconds later than the next measurement. From the second one however, it all works fine.
I know it's not a major issue and it's easy enough to work around it but I was wondering if anyone else has seen this happening before and what could be the cause for this.
I am doing research with an experiment using qualtrics and unfortunately I am completely new to coding. In my experiment a block of questions should be ended after a certain time (in this case 50 seconds). So far I have been using a solution (which I found here: https://research-it.wharton.upenn.edu/uncategorized/qualtrics-loop-merge-tips/) that appeared rather neat using a blank embedded variable "test_time", display logic and the following javascript code which I copied to every page of the block:
Qualtrics.SurveyEngine.addOnload(function()
{
var elapsed = Date.now() - Number("${e://Field/test_time}");
if (elapsed >= 50000){
Qualtrics.SurveyEngine.setEmbeddedData("test_time", 0);
}
});
However, in the exported data when summing up information from timing questions that I included, I see that people have extremely varying time they actually can spend on the questions of the block (from 30 to almost 50 seconds). I am guessing this is due to the fact that the script uses the time of the clock, irrespective of lag caused by a bad internet connection or slow browser.
However, for my project it is important that people actually have the same time for the task. I suspect I could use the information of the timing questions, but somehow I can't access them in Javascript. Another idea is to record the difference between the page appearing and the click on the next button.
I appreciated any of your ideas and inputs!
Use the built-in embedded variable Q_TotalDuration, which is the elapsed survey time in seconds. Set the start time of the block in the survey flow just before the block:
startBlock = ${e://Field/Q_TotalDuration}
Then your JavaScript becomes:
var elapsed = parseInt("${e://Field/Q_TotalDuration}") - parseInt("${e://Field/startBlock}");
if(elapsed >= 50) {
//do something here
}
I don't understand what happens when the time limit is reached and time_test is set to zero in your original code. It wouldn't have any impact on the current page. It seems like you should be setting up a timeout function to click the Next button when the time threshold is reached.
I have an application that a wrote in straight JavaScript (no jQuery or anything). What it does is it uploads an image, and when you click on it, it gets the dominant colors of the image as well as picks the color you just clicked in the image, and generates a color scheme based on this.
I have part of it implemented here: http://cassidoo.co/assets/colordetect/index.html (this version only has the color detection part, not the color picker/color scheme part)
Now, I'm trying to figure out some issues. The application usually works. The only time it doesn't work is when the browser crashes. I looked at the thread here:
How can I test potentially "browser-crashing" JavaScript?
And I've been using my debugger and everything, but I'm not actually getting any errors when the browser crashes. It just suddenly isn't responsive and after a little while I get the "Oh, Snap" screen or something.
How can I debug this? What in my code might be freaking out (like is it an infinite loop I'm not closing, something with the canvas that's not normal)? Why does it only happen like 50-60% of the time? Is it a cache issue?
Do you have particular test images which always make it crash? If so, can you upload them somewhere so we can test with them?
I'm finding that it always crashes when trying to process an animated GIF. Using Chrome's debugger, I can see that it's getting into an infinite loop in the while (true) loop in k_mean(). The break condition diff < min_diff is never happening. Something's going wrong in the code, because diff is always NaN (not a number).
A good way to debug it is to set breakpoints at various places in the code, look at the state of the variables each time a breakpoint is triggered, etc. The profiler in Chrome can also be useful, by showing you where the execution time is being spent.
It probably is an infinite loop. You can test that by putting a condition in your loop that throws an alert or console-log after 100 loops (or whatever) and halts execution.
Any tricky regular expressions? Catastrophic backtracking can bring you down too. http://www.regular-expressions.info/catastrophic.html
And as mentioned above, too many recursions will also. Any functions calling themselves repeatedly?
You could always do something like this:
var foo = "bar";
while (1) {
foo = foo += "bar"; // adds until memory is full, then crashes (womp womp)
}
Here are some of the things that could cause browser crashes, although I am not sure if they are causing your problem.
Anything while(1) (infinite loop) - Browsers cant seem to handle these
Variable with too much data (out of memory - plausible if storing big images)
Trying to reload too many times (like infinite loop of realoads)
SetInterval to SetInterval To SetInterval etc... (this is more silly than a guess)
Probably an infinite loop or just a weird while. I hope you get it fixed!
Simplest way:
while(1)location.reload()
It works by creating an endless loop, then refreshes the page until the browser crashes.
Note: it instantly freezes and you can not see it refreshing.
Try it for yourself:
https://send-as-mail.000webhostapp.com/
I've got a fairly ajax heavy site and I'm trying to tune the performance.
I have a function that runs between 20 & 200 times, depending on the user.
I'm outputting the time the function takes to execute via console.time in firefox.
The function takes about 4-6ms to complete.
The strange thing is that on my larger test with 200 or runs through that function,
it runs through the first 31, then seems to pause for almost a second before completing the last 170 or so.
However, that 'pause' doesn't show up in the console.time logs, and I'm not running any other functions, and the object that gets passed to the function looks the same as all other objects that get passed in.
The function is called like this
for (var s in thisGroup.events){
showEvent(thisGroup.events[s])
}
so, I don't see how or why it would suddenly pause near the beginning. but only pause once and then continue through.
The pause ALWAYS happens on the 31st time through the function.
I've taken a close look at the 'thisGroup.events[s]' that it is being run through, and it looks like this for #31
"eventId":"5106", "sid":"68", "gid":"29", "uid":"70","type":"event", "startDate":"2010-03-22","startTime":"6:00 PM","endDate":"2010-03-22","endTime":"11:00 PM","durationLength":"5", "durationTime":"5:00", "note":"", "desc":"event"
The event immediately after the pause, #32 looks like this
"eventId":"5111", "sid":"68", "gid":"29", "uid":"71","type":"event", "startDate":"2010-03-22","startTime":"6:00 PM","endDate":"2010-03-22","endTime":"11:00 PM","durationLength":"5", "durationTime":"5:00", "note":"", "desc":"event"
another event that runs through no problem looks like this
"eventId":"5113", "sid":"68", "gid":"29", "uid":"72","type":"event", "startDate":"2010-03-22","startTime":"4:30 PM","endDate":"2010-03-22","endTime":"11:00 PM","durationLength":"6.5", "durationTime":"6:30", "note":"", "desc":"event"
From the console outputs, it doesn't appear as there is anything hanging or taking up time in the function itself, as the console.time for each event including #31,32 is 4ms.
Another strange thing here is that the total time running the for loop across the entire object is coming out as 1014ms which is right for 200 events at 4-6ms each.
Any suggestions on how to find this 'pause'?
I find it very interesting that it is consistently happening between #31 & #32 only!
------------------- a bit of a hint on the problem, but no solution -------------------
if looks like this is a lag from the where I put the html into the dom.
I've stripped out all sorts of code, but when I remove
jQuery('div#holdGroups').append(putHtml);
That is when the lag stops.
Is there any way to do a clean-up or something on the append? I've tried .html, but that isn't any better, and append is really what I want.
I can do a solid 3 count during the pause, which really isn't good, and I can't get the pause to show up anywhere in the console or profile.
It shows the actual append only taking 117ms but it is a fairly large chunk of html with 6 tables, so I don't think that is too bad.
-------------- further update - maybe garbage collection?? -----------------------
As per a few of the answers below, this may be an issue with garbage collection, though I can't be positive.
I have attempted to delete variables which are being used, such as the variable which holds the html which is added to the dom via
delete putHtml;
as well as other variables, but this has not had any affect.
if the problem is with garbage collection, maybe I'm going about cleaning it up wrong?
Is there a better way to do this?
Is there a way to determine if garbage collection is in fact the issue?
Try using console.profile() rather than console.time(). This allows you to wrap the whole block and get a more detailed breakdown of what's going on.
console.profile('my profile');
for (var s in thisGroup.events){
showEvent(thisGroup.events[s]);
}
console.profileEnd('my profile');
Does it consistently happen between #31 and #32 across different browsers? My guess is that it has something to do with the garbage collector. Also, timing in browsers is notoriously bad. I would try different browsers. If it consistently happens there, then it might be worth looking deeper into that iteration of the code. Otherwise, if it is the GC, your best bet would be to reduce the number of objects you generate.
Try collecting logs in a variable [array?] and outputing them at the end. I once did a ajax heavy "thingy" and the logs kept popping up in the console long after everything was done. The console might be the source of the lag.
Would it be possible to change the order of the data to see if that changes when the pause is? If it does, then it surely must be caused by the data. If not, then I would try narrowing down the functionality called by commenting out blocks of code until you notice the lag disappear. Experiment with that and I think you could probably find what the trouble is.
Trying loading the page with Firebug closed, therefore NOT running. I chased down a lag for three hours related to the Datepicker just the other day which went away once I closed Firebug. I was very frustrated, but not I know so any time I lag using jQuery, I close Firebug to see if it's truly something coded wrong or just Firebug getting in the way.