Drawing a SVG with d3.js while tab is in background - javascript

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.

Related

React Native Android: Is renderToHardwareTextureAndroid working?

I am having performance and "jank" issues while scrolling on a Android React Native app. The JS FPS drops from ~60fps down to ~3-10fps while scrolling.
The content being scrolled DOES include images containing transparency and text layered over images. If I remove the images, performance increases significantly.
The above scenario sounds like a perfect case for renderToHardwareTextureAndroid. That said, enabling this property on a View containing the images/text seems to have no effect at all.
How can I confirm this feature is truly turned on and working as expected? Is it possible that something I am doing/not doing is forcing the hardware rendering to not take place?

Scrolling Behavior of Background Image on Deployed Website Is Erratic. It Is Supposed To Be Stationery, Expected Behavior On Local Build

Built a Jekyll website based on a 3-party theme (MASSIVELY).
Code of website available here: https://git.ikrypto.club/FNB_Japan/FNBJapan
When you visit the deployed website, the background image does not remain constant as expected (You can kind of see the expected behavior on the theme demo, https://iwiedenm.github.io/jekyll-theme-massively/ (Edit: This is actually a better example, https://massively.ghost.io/ ). Basically, the background image is expected to remain constant, and the foreground should scroll with the user.).
You can witness the difference in behavior if you go on our website, https://fnb-japan.info .
However, when the code is ran locally and built with
bundle exec jekyll serve
The background image does not move (as expected). What's happening and how can I remedy it?
Note: It appears that this problem only appears on FF Nightly, and not Chrome
Edit: This appears to be a problem with Firefox Nightly, as opposed to the website. This question is technically resolved.
Edit 2: It appears that the problem persists, and is due to a bad implementation of parallax scrolling causing parallax to flicker.
Edit 3: This problem only occurs once the window is of a certain width, and the difference isn'ta ctually between local/deployed but rather different window sizes.
The background div (#bg)
is being transformed by
this code in the bundled parallax plugin (as evident from setting a "break on attribute modification" on the bg element in the Chrome inspector), which in kind seems to be activated by this invocation:
// Background.
$wrapper._parallax(0.925);
Removing those lines should get rid of the parallax effect too.

Chrome - background-size: cover;-based gallery causes performance issues

I'm building an app using Vue 2. There's a page that contains a simple image gallery that contains about 20 images and one large page background image.
The background image of the page itself is actually contained in a fixed div element that is position: fixed;, has 100% width and height and uses background-size: cover; to display the image.
All of the ~20 items in the gallery as well are using div elements with background-size: cover; displayed in a 3-column grid and the images are displayed using the dynamically generated background-url CSS property using a Vue computed property. The image paths are never being changed so they aren't being recomputed constantly AFAIK.
The performance of this page in Chrome is abysmal, loading takes forever (those are some high resolution images, though, 4K in width) and once the images are loaded I can somewhat interact with the page but everything is extremely laggy and sometimes the page stops responding completely.
On the other hand, in Firefox and Edge everything is basically buttery smooth, both during the loading of the images and during the scrolling/rendering. The interaction with the app is never blocked.
What I remember trying to fix this is replacing the div elements with regular img tags and loading up images using those. Also, I've tried caching the images, I've tried using static image URLs for testing purposes - the same thing happens every time - other browsers handle it well, Chrome is choking on it.
Here's a screenshot of the performance summary in ~30 seconds, from the moment I click the page URL to the moment that basically everything is loaded and the browser is still struggling to render anything and process any interaction with the page. Obviously the painting phase is an issue here:
Any advice? Thanks!
This question is hard to answer as it is a very specific problem.
You can analyze what is causing this behaviour in chrome by using the developer tools:
Open the developer tools in chrome by pressing "Ctrl+Shift+I".
Go to the tab "Performance".
Hit the record button and do the action which has low performance.
Hit stop and you get a breakdown what happened in the background.
If you don't find the issue with above suggestion, you can post a detailed screenshot of the performance breakdown here, I might be able to help you with it.

Is it possible to reduce the memory allocated by Google Chrome for my web page?

I am trying to make a website with a minimalist feeling to it, so I put a fullscreen image on the background as background-image of body. I have a transition: background-position 1s set as a CSS rule for body and an easing function, to create a smooth scrolling effect when going to other pages in the same HTML file (I have no actual scrollbar, just navigation elements). The thing I noticed was that once I started scrolling, the memory reserved by the page went from a small 77MB to over 500MB! I tested this in Firefox, but it doesn't seem to happen (either because pages have no separate processes or memory allocation works differently, I imagine). Why does this happen in Google Chrome and not in other browsers? And how can I reduce the enormous amounts of memory reserved by my page?
To give some information on what I am using:
Browser: Google Chrome
RAM: 8GB The page uses javascript with the
following plugins:
jQuery
Bootstrap
Background image dimensions are: 1440 x 540
A few possible causes of the problem:
The image is too big to be rendered with a transition and an easing function.
I should not use background-image for this, but create a new <img/> as a background.
I somehow only checked it with developer tools open in Chrome, increasing the memory allocated.
It's not the image causing the problem, but the web fonts I scroll simultaneously with the background image, also using transition and an easing function.
And I want to add that maybe this is not even a problem after all, it's just that I have never seen a page go over 300MB with memory allocation.
Not sure if this should be posted as a comment instead, however:
Nothing you can do about that. Chrome trades RAM for performance.
For instance each chrome tab runs on its own process for that purpose.
I had cases when a single youtube tab took over 1.5gb memory & virtual memory.
Even a blank tab takes 45mb memory for me.
So there is no issue with your code at all.

jquery animation freaks out in background

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?

Categories

Resources