The CSS transform and opacity changes on SVG elements aren't hardware accelerated
Reported by
monfera....@gmail.com,
Nov 17 2016
|
|||||
Issue descriptionUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36 Steps to reproduce the problem: 1. See how SVG transforms are NOT GPU accelerated (repaint happens rather than compositing); green paint box flashing like crazy http://codepen.io/monfera/pen/JKOqyY 2. In contrast, see how HTML DOM transforms ARE nicely accelerated; no green repaint boxes flashing there http://codepen.io/monfera/pen/BzmERz 3. What is the expected behavior? I'd like that the most basic compositable operations i.e. transform and opacity be composited rather than repainted by SVG. For bonus points I'd like this behavior not only for setting these via CSS but also via the corresponding SVG attributes What went wrong? Lots of paint Did this work before? No Does this work in other browsers? N/A Chrome version: 54.0.2840.98 Channel: stable OS Version: OS X 10.12.1 Flash Version: Shockwave Flash 23.0 r0 With the huge proliferation of data visualization, please no longer treat SVG as a secondary citizen and treat it to the optimizations the (arguably more difficult) HTML DOM has already had for a few years.
,
Nov 17 2016
Thanks for the fantastic comments! The thousands of points seems like a stretch. But the reason for mentioning opacity too is the following. More and more data visualization relies on rich datasets, and readers see great value in details rather than just aggregates such as barcharts. So the alternative for such cases are these: 1) Use Canvas2d or WebGL, and atop of it, reimplement (poorly and informally) a chunk of SVG, just to have OK speed. 2) Assuming a fast and temporally (not just spatially) scalable SVG, use its awesome functionality, resulting in fast loading JS code; a LOT can be achieved in datavis and UX by just transforms and opacity (tweening, fading items in/out, and making more detailed elements appear/disappear on zoom and pan). We're currently superimposing SVG, Canvas, DOM etc. layers and going through hoops to bring the fantastic SVG functionality to with dynamic, interactive content. It's great that work is in progress toward that, thanks for the pointers, I'll check out these tickets! Also, the Chrome Canvas2d text rendering and line drawing speed for thin lines is amazing! Perhaps it's useful to keep this ticket around as it's more of a userland feedback rather than a (technically clearer) internal architecture note. SVG is so great for a LOT of use cases and despite D3 etc. it's getting more and more underutilized and hackishly substituted while we have just scratched the surface of its value - it's a declarative interface and could in theory be as fast as our manual Canvas2d and WebGL solutions for what it covers. Finally, a few unrelated gists - mostly with SVG - for fun :-) http://bl.ocks.org/monfera
,
Nov 17 2016
Yes, it kind of s*cks when you have to use a bar of steel to drive nails, when there in theory exists a perfectly good hammer... Oh well, better fix that hammer. > Finally, a few unrelated gists - mostly with SVG - for fun :-) http://bl.ocks.org/monfera Cool!
,
Nov 17 2016
fs, isn't there already a bug for this?
,
Nov 18 2016
There's issue 330199, which, as written, can be considered a subset of this. There's issue 644146, which is kind of this, but vague. Then there's probably bits and pieces that would/could make up the building blocks for this.
,
Feb 3 2017
Issue 688243 has been merged into this issue.
,
Feb 3 2017
We are actively working on "slimming paint v2" which is a large project to rework compositing and will let us composite inside SVG. I am hoping this will be done in Q2.
,
Jul 1 2017
How long for this to be fixed? We badly need smooth (60fps) parallax scrolling in our SVG web animations. Currently even a couple of layers makes the scrolling jitter.
,
Jul 5 2017
Muad'Dib, we're still plugging away at this project. A large part just shipped recently: https://groups.google.com/a/chromium.org/d/msg/paint-dev/U3H0t72yFwo/cldxgGyNAQAJ. I expect this will take at least a couple more quarters. Until then, I'd recommend layerizing svg using layers in html like so: http://jsbin.com/fubuloc.
,
Jul 13 2017
I also filed an issue on this as well, https://bugs.chromium.org/p/chromium/issues/detail?id=688243, and there are a few more issues in the comments. It would be nice to collocate the stars collected somehow, because the stars just for this bug don't tell the full story and I do believe people need this, for data visualization and product uses among others. SVG helps us build a more performant web, we can serve such a small amount of KB for the effect that many MB grants us in gif or video.
,
Jul 13 2017
Sarah, does the approach in http://jsbin.com/fubuloc work for you today?
,
Jul 13 2017
OP here - the linked example is almost identical to the original example https://codepen.io/monfera/pen/BzmERz ie. it didn't feel sufficient, and the issues with the workaround, mostly from a dataviz PoW, are (probably very incomplete quick llst): 1. You lose the projection space - 1st projection is in HTML space (e.g. absolute positioning), and within the <SVG>, you use local positioning - while a trivial case is obviously easy, a more complex scenegraph is more complex, especially if it needs to be responsive to screen size 2. The toplevel <SVG> functionality eg. viewport / view box, aspect ratio etc. will be unavailable 3. For anyone who wants to export just one SVG file, it won't be possible 4. SMIL can't be used on HTML (minor point as it's no longer deprecated but not prevalent either) 5. A lot of useful functionality is present in SVG that cascade down the scenegraph, for example, transforms (incl. scaling and rotation, needed for complex animation), specification of styles / presentation attributes (stroke-width) 6. User has to be conversant both in SVG and HTML, and know how to fuse together the projections 7. The scalability of using LOTS of <SVG> blocks on a HTML page is questionable, as this tag is probably a heavier weight object than e.g. a <circle> tag; also, markup itself (whether loaded or generated from data) is a lot heavier 8. Lots of SVG functions are thrown out of the window, the most important in dataviz being clipping, but also masking, filters, def, symbol... 9. And most importantly, the proposed approach is appropriate for a 2-level scenegraph but realistic dataviz is 4-10 levels deep ie. a singular HTML / SVG level cut needs to be established; ie. only one scenegraph layer can thus be HW accelerated. If there are nested animated transforms, only one level can enjoy the GPU acceleration. 10. Also for this reason (arbitrary cut between HTML and SVG) there's a 'chasm' between the two which makes scenegraph refactoring, experimentation etc. real hard and the results very rigid. All in all, from a dataviz viewpoint, it feels like the workaround is only applicable for quite specific niche cases where it already is used for this purpose.
,
Jul 13 2017
... there's also the issue of Z-ordering, obv. the 'chasm' will represent a Z-directional dividing plane between the HTML and SVG space; also, blending / opacity. Ie. it may be hard or impossible to achieve a reasonable view by creating little svg primitives and combining them in HTML. One might as well turn DIVs into circles, hexagons etc. which is also often done.
,
Jul 13 2017
Yeah, the jsbin demo way of implementing doesn't help even one single use case for me or many others. I agree to all of the points above. It's fine for pretty much only that demo. You lose all of the positioning, so you end up having to absolutely position everything in a container and shift everything around- absolutely NO ONE is going to do that for a complex SVG. Here are some examples of my work so that you can see what I mean: https://codepen.io/sdras/full/waXKPw https://codepen.io/sdras/full/dPqRmP https://codepen.io/sdras/full/YNpaoJ Here are some of Olegs: https://codepen.io/sol0mka/full/ogOYJj/ https://codepen.io/sol0mka/full/OyzBXR/ Here are some of Chris Gannon's: https://codepen.io/chrisgannon/full/WvJMXP https://codepen.io/chrisgannon/full/PzRWNO There's no way we would all extract every SVG piece we need to move for these and reinsert them individually into the DOM and position each one. It would be a terrible workflow, and break accessibility. It would rob us of everything SVG is good for. I'm sorry to say, that's no real workaround for anything other than exactly that demo, which makes it a poor demo. Thanks for taking your time to understand this issue! I really appreciate it.
,
Jul 13 2017
Good idea to add examples, illustration is key. This small dataviz mock http://bl.ocks.org/monfera/35be5626a47110312c35 doesn't look much and may be a small part of a real dashboard, yet it uses up to 7 levels from the root dashboard: > document.querySelectorAll('svg > * > * > * > * > * > * > * > *') yields stuff like body > svg > g.dashboard > g.row > g.bandlineCell > g.bandline > g.sparklineSliderClippedStationaryPart > g.bandlineHolder > g.valuePoints > circle.point with transforms across all layers, clipping, and less HTMLable shapes such as lines. Use config sliders in eg. Layout tweaks on the right to see how a meaningful scenegraph has nice reconfigurability properties but involves quite a bit of structure. It has 622 SVG elements incl. non-leaf nodes: > document.querySelectorAll('svg *') Just like Sarah's examples, it's still small so it works 60FPS despite no HW acceleration, but the dataviz design space is definitely constrained by current SVG performance.
,
Jul 13 2017
Thanks for the examples. I think we all agree that layerization is needed to reduce repainting in SVG. We're working hard on it.
,
Jul 13 2017
,
Jul 13 2017
thank you!
,
Oct 14 2017
I start to understand the first reply to my original filing (by f...@opera.com), due to three new experiences: - I haven't benchmarked it in FF but https://hacks.mozilla.org/2017/10/the-whole-web-at-maximum-fps-how-webrender-gets-rid-of-jank/ basically concludes that it's most often cheaper to just redraw all things than to do compositing with a large number of things - Implementing WebGL features at Plotly, we also ran into the question of redrawing all vs preserving things and compositing as much as possible - which I think is fairly analogous to the question of GPU acceleration or some other way - My own experiments with Chrome HTML DOM showed that I could animate almost 2x as many small <div> scatter points at 60FPS when using `translate(x, y)` than when forcing GPU compositing with `translate3d(x, y, 0)` - I understand how compositing is not necessarily the answer especially with large scenegraphs and how GPU power can be harnessed via drawing as a perhaps better route So yes, it's totally valid to rephrase the request as a general need for speedup. I think it should be doable b/c currently there's an approx. 3 orders of magnitude speed improvement when rendering points with WebGL. I think the SVG DOM does a lot of extra work even though the user's only chance is to only see the render effects (eg. no event handlers attached etc.)
,
Dec 13 2017
Sorry to keep bugging everyone, but is there any traction on this? We're coming up on a year since the original bug was filed. What do you need to push this through? Happy to help where I can. Thanks!
,
Dec 13 2017
Sorry to pile on, but I have a slightly different use case than what Sarah and OP have posted already. I have the same animated svg posted multiple times, and even though it would seem that having the same SVG with the same style multiplied on the page the additional elements would be logarithmic in CPU usage, but they seem to be multiplicative. SVG with animation https://codepen.io/markis/pen/baGKPE SVG with animation multiplied https://codepen.io/markis/pen/MrYGLM GIF https://codepen.io/markis/pen/vpYvqd GIF multiplied https://codepen.io/markis/pen/vpEjwe With only one animated svg, the browser is still usable. But once this gets duplicated about 30 times on a page (which in our case is a real possibility), the cpu hits about 100%. And for some users becomes completely unusable. For now, we are resorting to using GIFs, but it's not ideal.
,
Dec 13 2017
@c#21: In your particular case all the "layer triggers" ('translateZ(0)', 'perspective' and 'backface-visibility') is more likely to do harm than good - for each frame all the parrots will be "rerasterized", and having them be on layers will then add additional steps to produce the final result.
As for the "multiplicativity", there's really no sharing going on in this case, so the scaling will be by area (pixels that needs to be [re]rasterized) and node count (number affected by the 'fill' animation). The complexity could be factor, although it can be seen as increasing the average cost of a pixel. The complexity per pixel is observed in the GIF case - there's only 31 things to paint, and no styles need to be updated. For the SVG case there's 31 * ~8 shapes that need to be repainted/rastered each frame, and also style updates for 31 of the shapes. (You can gauge this yourself using the "Performance" timeline in DevTools.)
,
May 22 2018
Any news or timeline on this one, by some chance?
,
May 23 2018
Nothing new, no timeline. Things are moving forward, but we have yet to reach the point where this issue is addressed.
,
Jun 8 2018
Issue 675801 has been merged into this issue.
,
Jun 8 2018
Can we please make some progress on this? It has been years now and this keeps getting shuffled off to new issues. It's very frustrating to make data visualizations or use the platform as intended. Please and thank you.
,
Nov 8
So much of our new ideas & designs are focused on manipulating SVG graphics and it would be so helpful to see this feature in browsers. We created a SPA where a user could manipulate potentially thousands of groups of svg nodes, however, we couldn't push further than a few hundreds. Would love this feature in.
,
Jan 11
+1 to this. I work on a data visualization product as well, and fast SVG is very desirable for us! As is, we might have to go the route of reimplementing a subset of SVG on top of canvas2d. |
|||||
►
Sign in to add a comment |
|||||
Comment 1 by f...@opera.com
, Nov 17 2016Status: Available (was: Unconfirmed)