Javascript setInverval seems slow? - javascript

So I am trying to do a setInterval that checks the placement of something on the page. Issue I am having is that if I set it for 10, 100, 250 it seems to be very slow and slows scrolling down.
setInterval('functionName()', 10);
setInterval('functionName()', 100);
setInterval('functionName()', 250);
UPDATE: The reason for the function is to move an element down the page when the user scrolls. The issue is that it is a Facebook app, in an iFrame, that is larger than the screen. I can't seem to find a way to attach the onScroll property outside of the iFrame, to Facebook (or maybe you can?!? I haven't had any luck yet) so I am being forced to use this method. Basically, it will grab the scroll height that Facebook passes in and move the element down the page. It works...but it seems to slow even scrolling down.
Is this something I just can't get around?

You're doing something every 10ms. That very well could intefere with the normal operation of the browser. The browser interface is blocked whenever javascript is running.
Perhaps if you describe what you're trying to do with the interval timers and post your code, we can suggest better performing ways to do that.

The minimum time resolution for setInterval() and setTimeout() varies by browser, and in some cases can be as much as 15 or 20 ms (some articles state up to 75ms). Your attempt to perform an action at higher resolutions (shorter intervals) is really more of a request to the browser -- there's no guarantee. Requests at resolutions higher than the browser's capability will be "clamped", and run no more frequently than that minimum. And of course, if the browser's workload is sufficiently high (as it is likely to be given the assurance of a continually called function), the interval may be significantly greater.
As a side note, it's best not to provide your function argument to setInterval() as a string. Doing so will cause that function be evaluated in the global scope. Instead of this:
setInterval('functionName()', 10);
you should use this:
setInterval(functionName, 10);
You should reconsider the need for running your function so frequently. Perhaps there's an event-driven alternative.
References: MDN on minimum delay

JavaScript is, by it's very nature, single threaded. That means that your JavaScript runs in the same process as your browser's UI.
So, whenever the browser is executing your JavaScript, it has to halt whatever it is that it's doing (which, quite often, might be drawing the page in the browser window), and run your code.
Since you are running a piece of code 100 times per second (1000 / 10), you are simply hindering your browsers normal form of operation!!

My guess is that functionName() is slow. 250 shouldn't be too bad for modern browsers. Post the function and we'll see if we can improve it.

Something that hasn't been mentioned: you're passing a string to setInterval when you really should be passing the function object itself:
setInterval(myFunction, 5000)
What happens when you give it a string like "functionName()" is that it's eval'ed, that might be the source of some of the slowness.

Related

What differenciates browser.alarms.create from setTimeout/setInterval in WebExtensions?

I am creating a WebExtension for browsers. So I found out about the browser.alarms API. It basically allows you to set a (reoccurring or one-time) alarm and a callback will be fired.
Now, we've had such a feature this for a long time in JavaScript as in setTimeout and setInterval. So what is the difference to these ones? Why or in what cases may I prefer the one over the other?
I mean the main difference is obvious: You can only refire it e.g. in minutes, not seconds. Although, I think with when you can also unregister and re-register it in millisecond precision, but I think the API may be intended for longer periods, i.e. minutes. (I am just guessing here.)
So why should I use it instead of a simple setInterval/setTimeout callback?
setTimeout/setInterval time span is limited by 2^31-1 = 2147483647 i.e. ~24 days. Values less than 0 or bigger than that are cast into int32 range, which can produce unexpected results.
setTimeout/setInterval is part of standard DOM, not the isolated world, so when you use it inside a content script, the web page script can clear them accidentally via clearTimeout/clearInterval.
Workaround: post a message to the background script so it sets the timer and sends a response upon finishing.
Event pages (those that have "persistent": false in manifest.json) won't wait for setTimeout / setInterval before unloading due to inactivity and won't wake up for such a timer so you can only use them for a very short time (currently the event pages are guaranteed to live for 5 seconds).
Within these designated limits you can safely use setTimeout/setInterval.
In addition to what has been posted, the alarm API seems to be more reliable:
if you setup alarm in the past, it will fire right away
if you setup future date and your PC wakes up from hibernation after the date, it will fire right after waking up
if you setup 8 hours from now, it will fire 8 hours from now (if your PC is on) no matter how long was your PC sleeping / hibernating in the meantime
See https://discourse.mozilla.org/t/how-reliable-are-alarms/40978/8?u=rugkx, thanks to Juraj Masiar from the Mozilla Community.
To quote from the documentation on MDN:
This is like setTimeout() and setInterval(), except that those functions don't work with background pages that are loaded on demand.

Is there any impact of having a script running x seconds in the browser?

I've created a script that runs every 1 second looking for a change in a value. Consider the code bellow:
setInterval(function() {
var inputOne = jQuery('#0_img_file');
var inputTwo = jQuery('.0_img-file').attr('src');
return function() {
if (inputOne.val() !== inputTwo) {
jQuery('.0_img-file').attr('src', inputOne.val());
}
}
}(), 1000);
So heres my question, could this script affect the site experience to the user or any kind of other stuff am not aware of?
I know there is functions in jquery like onChange, change etc but it only works if the user changes the value automatically, I've noticed it does not capture changes if other scripts change the value of an input.
First of all your code runs 10 times per second, not once. However, your browser is likely running on a computer with at least 2 multigigahertz cores with hyperthreading, megabytes of caching on board and you name it. So no, repeating a trivial task every 100ms (or 1s) is not going to noticeably slow down your browser, JS is usually rather fast.
Just don't run 100 jobs like this, you will start to feel it. And of course, you should just hook onto events of the scripts modifying the values, instead of polling for changes, which should be possible just fine with Javascript - due to its prototyped nature it's trivial to plug into existing code.
I've noticed it does not capture changes if other scripts change the value of an input.
That's because you probably use .attr('value', something) or .attr('checked', true') instead of .val(something) and .prop('checked', true).
So heres my question, could this script affect the site experience to the user or any kind of other stuff am not aware of?
Of course it can. Especially if the script make some heavy operations. Many browsers execute Javascript in only one thread. So when your script start, the browser will freeze during it's execution. If you have only one light script, it's ok. But if you abuse of this method, you will have some performances problems.
Well, I think the site will be little slower. The script calls a function every 1 second, so it will not have much problem on good computers. Besides, not everyone has good computers. Some users uses slow computers will have problem in perfomance, so usinh other way is needed.

is Javascript's setInterval loop a resource hog?

I'm designing an app to run on very low spec machine..and i needed it to be efficient as possible..
I needed to issue around 10 intervals at every second that simply makes an ajax call.. and then does a few add/remove classes and (think of it as SERVER Status monitor)
I know in FLASH (oh good old flash days) having a lot of intervals can cause processor spikes .. so i'm very conservative with issuing setIntervals in AS 2.0 before.
I was wondering if this is the same case with JS? or is it alright for JS to have a bunch of intervals (that does lightweight tasks) running? I noticed a lot of sites do this , even facebook has tons of intervals running, loading scripts, etc..
And oh, for one interval, I wanted to run it at 50ms (it loads as status.php link) ... this ok?
I could probably optimize my interval calls, no problem but i'm just wondering how "heavy" or "lightweight" background intervals are in JS..
Thanks all
10 intervals at every second meaning a call every 100ms should not be an issue in my opinion, but if you ask me I would fire a call every 250ms.There is not much difference between the two that the user will notice.
Also make sure that there is a mechanism to handle long running response from server in case there is a delay and stop the interval firing if there is drag.
As a matter of personal feeling, I tend to prefer setTimeout over setInterval -- to the point I don't use setInterval at all.
The issue that you might run into is if one process takes longer than it should -- let me give you an imaginary situation:
window.setInterval(takes100msToRun, 50);
window.setInterval(takes50msToRun, 50);
window.setInterval(takes20msToRun, 50);
The problem is that the first interval will take longer than it should, so the second two interval requests are now behind and the browser will try to catch up by running them as quickly as then can. The second interval takes 50ms, -- so its still running behind when the third interval hits.
This creates an ugly situation that can lead to a lot of drag.
On the other hand, if you setTimeout, then you aren't say "Run this every 50 ms", but rather "Run another one of these 50ms from we finish." (Assuming, of course, that the functions set up another setTimeout to re-execute.)
It is absolute rubbish for things that need good clock timing, but its superior for everything else.
setTimeout and setInterval will affect performance, but little.
Since there are lots of functions triggered/listening/running in the browser.
Even a tiny operation like move your mouse to vote up for this answer, there are thousands of events got triggered, and tens of functions start running.
Don't use setInterval. As a matter of fact, the library underscore doesn't use it either.
See how they implement the _.throttle without setInterval.
http://learningcn.com/underscore/docs/underscore.html#section-66

Is it possible to have "setInterval" set too fast?

I have a setinterval function in my javascript that I want to be as fast as possible, i.e. check the status of an event every 1ms. Is it possible that this would be asking too much from a user's browser? It seems to work just fine, but I am wondering if its a bad practice.
It is not only possible, it's quite common. It's a race-condition by its very nature. If you depend on the code inside the callback to be executed before the next interval, use a recursive setTimeout instead.
Also, unless your interval is called lockUpBrowser, that duration between callbacks is likely much too short for realistic performance handling.
(function myRecursiveTask() {
// Do your task here
myTask();
if (!someConditionToAllowABailOut) {
setTimeout(myRecursiveTask, 100); // 100ms loop
}
}());
setInterval is not guaranteed to execute at precisely the interval specified.
It will execute as soon as possible, but since javasript is single-threaded and some other code may execute at this time your callback may be delayed.
If you're using setInterval with 1ms than you're probably trying to solve your problem in a wrong way.
Yes, if the function reference passed to setInterval takes longer to execute than the interval, calls to the function will queue and bog down the browser. If you're trying to perform an animation and want to change each step as fast as possible, there is a requestAnimationFrame function that should be used for modern browsers. Personally, I've never needed to perform a function faster than every 15ms.
I would certainly question the need for such an approach. What are you needing to check for every 1ms that you can't check for every 10ms, 100ms, or every second?
Are you 100% certain that the check functionality that you will run every will always execute in < 1ms such that you don't have multiple check processes stacking up to run.
How much memory and CPU does the process take, and are you going to potentially slow down the user's browser to the point where simply actions like scrolling become painful for the user?
is an while loop too slow for you?
while (condition)
{
//code block to be executed
}
i know i'm not ansering your question but, i think there is no better ways to do something like that...
Ben Cherry has a good article about this where he tests different browsers to find how fast setInterval can be before it becomes unreliable. The speed at which a setInterval or setTimout fires is dependent on the browser.
In particular, if you’re looking for consistent timer intervals across browsers, you have to use something >15ms.
So if you can set the time greater than 15ms you won't run into problems.

JavaScript execution hangs page momentarily

I have a web application which uses jQuery/JavaScript heavily. It holds a large array in memory, and the user filters it by typing in a textbox.
Problem: When the filtering algorithm runs, the application becomes non-responsive and the browser may even ask the user whether to let the script continue.
Optimally, I would like the filter function to run in a separate thread, to avoid non-responsiveness. Is this possible in any way? Alternatively, I would like to show a rotating hourglass or similar, but browsers seem unable to display animated GIFs when running heavy scripts.
What is the best way of attacking the problem?
Browsers execute scripts in the main event processing thread. This means any long running scripts can holdup the browser queue.
You should split your filter logic into chunks and run them on timeout callback's. You may use a gap of 0 mills between executions. 0 milli's is just a suggestion to the browser, but the browser will use the gap between subsequent callbacks to clear its event queue. Timeout's is generally how long running scripts are ought to be executed in the browser environment to prevent the page from "hanging".
This type of job is what Web Workers were designed for, support is patchy, but improving.
Expanding on my comment from earlier, given that you are processing an array you are probably using a for loop. You can easily refactor a simple for loop to use setTimeout() so that the work is broken up into chunks and the browser gets a chance to handle screen paints and user interaction between each chunk. Simple example:
// Generic function to execute a callback a given number
// of times with a given delay between each execution
function timeoutLoop(fn, startIndex, endIndex, delay) {
function doIteration() {
if (startIndex < endIndex){
fn(startIndex++);
setTimeout(doIteration, delay);
}
}
doIteration();
}
// pass your function as callback
timeoutLoop(function(i) {
// current iteration processing here, use i if needed;
}, 0, 100, 0);
Demo: http://jsfiddle.net/nnnnnn/LeZxM/1/
That's just something I cobbled together to show the general idea, but obviously it can be expanded in various ways, e.g., you might like to add a chunkSize parameter to timeoutLoop() to say how many loop iterations to do in each timeout (adding a conventional loop around the call to fn()), etc.

Categories

Resources