I have made a little animation that resembles the coverflow itunes uses as a screensaver on mac. It fetches a list with filenames using ajax and starts looping over them to randomly fill divs with them.
Demo code:
http://jsfiddle.net/FQmXK/4/
All of this works great but the problem starts when you minimize the browser or go to a different tab on google chrome. The animation seems to queue up a bunch of cycles and tries to execute them all when the window is opened up again. This is causing all sorts of problems, images being undefined, all kinds of flashing on the screen...
I was wondering if there is any established solution for this queueing behavior? Can I force it to execute all animation even if its not visible?
You can detect browser window focus :
Is there a way to detect if a browser window is not currently active?
And set a variable.
If the window is inactive, set a variable to false, and do not queue further animations
until the window becomes active.
This question discusses the same problem and provides a generalized solution:
How can I make setInterval also work when a tab is inactive in Chrome?
Related
I am attempting to use the data received from DeviceOrientationEvents to animate (rotate) a camera in three.js using three's DeviceOrientationControls. The controls are updated upon every animation frame, and everything works as I would expect. However, if I begin to scroll, then no DeviceOrientationEvent is fired again until the inertia from the scrolling is complete.
I have confirmed that these events are not fired (or at least not dispatched) during the scroll by logging to the console from within the DeviceOrientationEvent handler. I can see the events fired regularly up until the moment I begin to scroll, then stop, and then resume firing from the moment the inertia from the scroll is complete.
Manually stopping the inertia mid-scroll (by touching the screen) also causes the deviceorientation events to resume.
I have disabled all other scroll event handlers in my script. I have made all touch event handlers passive, have tried making them non-passive as well, and have also tried disabling all touch event handlers in my script altogether.
I am fairly sure by this point that this may be a function of how the processing of the scroll thread (which operates separately to the main thread) and the processing of IMU data are scheduled/queued in the browser, so that there may be no good solution, but I'm asking here in case there is something I've overlooked in my own troubleshooting. This does not appear to be an issue with three.js or the DeviceOrientationControls in three.js, but I've tagged this as three.js just in case anybody has ever come across this problem when attempting something similar.
My unique case for having DeviceOrientationControls enabled while scrolling is that scroll drives the animation of a "camera rig" (of empty objects whose rotation and position are animated), while moving the phone around rotates the camera itself. (It's a bit like being able to turn your head to look around while moving in a railcar.)
My testing has been on an IPhone 11 Pro, with iOS 13.5.1, in Chrome iOS 84, and Safari. I have not tested on Android.
iOS has slowed down repetitive JavaScript functionality during scroll for many years now. This is to conserve battery consumption, since it has to re-render the page lots of times while scrolling, so it halts other secondary commands until scrolling is complete. See here for more.
You could create your own custom scrolling functionality without actually scrolling down an HTML page by capturing vertical swipe gestures via 'touchstart' and 'touchmove'. Or you could use a library like Hammer.js to help you.
Context: I am working on a webapp that has to display some fairly complicated and constantly updating (multiple times per second) SVG images. The updates stem from a seperate server and the SVG is updates as soon as an update is received by the web frontend. The webapp is written in Scala.js and the image is created using the d3js library (see also: scala-js-d3). We currently only support Google Chrome.
Problem: Once the webapp has been in a background tab for a while, the whole site gets unresponsive once navigated to again. Depending on how long the app was in the background, it sometimes takes up to 20 seconds for the application to be responsive again. Is there any way I can solve this?
The solution that works best for me is a pretty simple one:
Once the application is in a background tab or minimized (can be detected using the Page Visibility API), I only update my model without drawing anything. Then, once the application is put into the foreground again, I re-draw everything. This fixed all of my performance problems.
I came across the same problem which I worked around by not doing transitions in background tabs.
mbostock shows a nice snippet for doing this at https://github.com/d3/d3-transition/issues/93#issuecomment-516452828
Helper method…
d3.selection.prototype.maybeTransition = function(duration) {
return duration > 0 ? this.transition().duration(duration) : this;
};
…to be used the following way:
selection
.maybeTransition(document.visibilityState === "visible" ? my_duration : 0)
.attr(…
Capturing the page visibility events one could then even adapt the transition time in such a manner that the transition time is reduced (thus the transition sped up) in such a way that it ends in about the same time had the page not been in a background tab.
If you are using setInterval() at the moment the browser might be 'punishing' you for running setInterval() in an inactive browser-tab.
You can fix this by either using requestAnimationFrame() or by monitoring the tab visibility and only using setInterval() when the tab is active.
This isn't a specific JS code issue, but more the way iOS deals with JS that is causing more problems on my site than most others.
On iOS only (it doesn't happen on Android) if I'm natively scrolling (up/down) and then try to activate some JS just before the scroll has finished (very quickly) then it completely ignores the JS.
I believe that Apple do this so that the UX always remains priority (don't let any crappy JS slow down the user), but in this case it's just a very simple piece of JS that I want to allow to run.
As an example, if a user is scrolling and then quickly presses a tab at the top of the screen that opens a fixed navigation panel then it won't register if the native scroll is still happening. If they press it again (the scroll has finished) then it works.
I'm also using a JS slider to scroll horizontally through images and if I try to scroll left/right just before the native up/down scroll has finished it sort of jumps and isn't good UX. I think it's prioritising the native scroll but still activating the horizontal scroll with some sort of delay.
It's not a massive problem, but not perfect. If everybody slowly navigated the site and waited for the native scroll to come to a complete stop, it would be great. But of course people won't do this.
I don't think preventing the default behaviour will do anything. I have tried to take over the native scroll before on iOS and I just don't think you can.
I think this may actually happen on many sites. I've just tried to find a good example by visiting stackoverflow.com on an iPhone and if you scroll quickly and then quickly hit a link before the scroll has finished it won't register. I don't think text links are as big a UX issue though, but a horizontal slider and big 'open menu' button at the top are much more likely to be hit quickly before the native scroll has ended (as you don't need to read something before you press it, like with text links).
I have various JS scripts on a site that would benefit from this being improved in iOS, so if I can understand a way around it, why it happens, what is going on, then I can apply individual fixes to each of those scripts.
Thanks.
The problem is not that iOS ignores javascript while scrolling (more precisely, while the scroll momentum is active). The problem is that, while that happens, iOS does not really register the position change of elements on the screen. In fact, if you have a handler attached to the scroll event, it will stop firing the moment you stop touching the screen, and then will fire just once when the scrolling stops.
Consequence? You think you're touching a link, but you aren't. The image on the screen has moved up or down, but, to the broswer, everything is on the same position, so, actually, you aren't touching anything (or are touching something different). I got very annoyed when I found this behaviour because, in my case, my page is full of images that are links to a gallery ... and if you touch them while scrolling, the gallery opens showing you not the image you touched, but another (The one that really was on that position when your fingers stopped touching the screen).
Is there a workaround? The only one that I know of is disabling the scroll momentum, but you lose scrolling performance.
I have an issue with jQuery ScrollTo.
It skips and there is a lag when applied to my page.
Here's a link to the jsFiddle example that works and here is the same code applied to my page that does not work.
It might function correctly on some machines but all the machines I have tested this on don't!
Might there be an issue with the amount of images I am using?
Is there anything I can do to overcome this?
The problem there is the background image. On "poor peformances machines", using a full page background image like you did and scrolling is not very efficient.
For instance, my machine at work lags as hell on your page, either using the top menu or regular scrollbar. On the otherhand, my MacBook Pro handles your page perfectly with a smooth feel when using the top menu to scroll.
I tested it using chrome on my machine, and removing the background image using developers tools. It now works perfectly. As soon as I put the background image back, it starts lagging again.
Its a bit jumpy on my machine (your site that is), but one thing i noticed that may help is that it is really nice and smooth smooth if i very quickly click back and fourth between 'Senior Executive' and 'Experienced Hire'.
Is there any callback or some calculation being done before, during or after the scroll perhaps?
I have a site, which upon clicking an image a lightbox pops up (eg http://www.huddletogether.com/projects/lightbox/).
Our customer still has some machines which run IE6 (upgrading is unfortunately beyond our control), so in order to block out some SELECT elements, I have used the old IFRAME shim trick (as described here: http://weblogs.asp.net/bleroy/archive/2005/08/09/how-to-put-a-div-over-a-select-in-ie.aspx).
However, I have the following problems:
The lightbox doesn't appear until the mouse is not longer hovering over the page - moving the mosue to a different window, or even just to the scroll bar causes it to appear;
While the mouse is over the page, the following doesn't happen:
Any jQuery animations related to the lightbox stop (or to be more precise, the animation continues in the background, only to have finished upon mouse out);
Animated gifs inside the lightbox stop running until mouse out;
Javascript in general stops until mouse out.
Everything seems to run fine in our other supported browsers (IE7 and FF).
Unfortunately I don't have a link to show you these effects, but hopefully I have explained myself enough for somebody to help (which will be very gratefully received)!
Edit:
Forgot to say, I know this is related to the IFRAME, as removing it causes the javascript to run fine, but obviously the ugly SELECT boxes bleed through the top DIV.
It sounds like you have something heavy running in a mousemove or mouseover event handler that's blocking animations, animated GIFs, etc.