Jump to content
GreenSock

geddski

Draggable Performance Jank

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

I'm trying to achieve 60FPS in my UI. I'm using an x,y Draggable, but cannot currently get a jank-free experience with Draggable which makes me so sad because otherwise I love this tool (and even joined the club). See the chrome profile timeline below. How can we fix this?

 

 

3b42ecfa2dca3e76192b59376368c434.png

See the Pen WrXmox by geddesign (@geddesign) on CodePen

Link to comment
Share on other sites

Hello geddski, and welcome to the GreenSock forum

 

Are you seeing this on Chrome (apple device) or on Chrome (windows)?

 

I'm not near my computer right now..

 

But by the looks of your codepen you might want to keep in mind that anytime you animate something with transforms.. dragging included you want to add position absolute or position relative on your element so it can be animated without affecting or triggering layout around its surrounding elements.

 

So i would add the CSS position property position:absolute on your #one CSS rule. So your element doesn't have to trigger layout for its surrounding elements.

 

In the Draggable Docs it states that you must have the element position as position absolute or relative. Taken from Draggable docs:

  • In order to make things moveable via their "top" and "left" css properties, you must make sure that the elements have their position css property set to either "relative" or "absolute" (that's just how css works).
And when testing you could test in codepen debug mode since testing accurate frame-rate in codepen can be buggy since codepen has a lot of memory leaks and blockades in place to protect against infinite loops. So it might not be the best place to test performance, due to the load on their servers and inconsistent loading. In codepen you can access debug mode by either switching to that view if you have a codepen pro account. Or just simply change the word in your codepen URL from /pen/ to /debug/ . Codepen debug mode runs your codepen without an iframe. So your pen isnt running within an iframe when in regular pen mode.

 

Also keep in mind, when testing performance and framerate in Google Chrome, the Google Chrome Dev Team recommends to make sure you debug or test in private browsing mode (incognito window) to make sure results don't get skewed by extensions and other factors that get disabled in private browsing mode.

 

:)

  • Like 1
Link to comment
Share on other sites

Hi Jonathan,

I'm on latest stable Chrome (v47) for OSX. I did as you suggested and switched codepen to debug mode. Same effect. In fact the reason I decided to reach out was because I'm seeing this jank in the app I'm building, so I'm positive it isn't the codepen runtime. 

 

Switching to Incognito was a good idea, to rule out any of my chrome extensions etc. Same problem :/

 

Adding position:absolute; to the element also had no effect on performance.

 

Switching it from a 3d transform (x,y) to a position change (left, top) did not improve performance either. 

 

As far as I can tell, something Draggable is doing causes certain frames to go over the 16ms budget, to around 33ms (< 30 FPS). See screenshot below. There doesn't appear to be any JS, compositing or painting happening to cause such a long frame. Notice all the empty whitespace. It appears that there are simply *two* Animation Frames firing in a single frame for some reason, causing frames that take twice the time. Strange eh.

 

98b260947687c31cf007f29c7250d705.png

Link to comment
Share on other sites

hmm, are you saying that you are actually seeing bad performance with Draggable in the CodePen demo? I've been dragging around for quite a bit and it all seems quite smooth. I've been talking to a few people about this issue and no one can verify that they are seeing a problem. Is performance noticeably worse in your app than it is in CodePen?

 

Just want to try to understand the issue more.

  • Like 1
Link to comment
Share on other sites

I'm equally baffled - Draggable's performance seems to be stellar and I can't seem to replicate anything like what you're describing. Furthermore, Draggable specifically throttles its actions so that rendering is only done on "ticks" (requestAnimationFrame). I can't think of any reason it'd even be able to trigger things multiple times between requestAnimationFrame ticks. Perhaps I'm missing something.

 

Do you notice any difference if you turn off autoScroll or if you use an older version of Draggable? (I'm shooting in the dark here). And you can replicated this on multiple systems? Nobody I've talked to can see the performance issues you talked about, so I'm having a tough time figuring out what could be going on. I definitely want to fix any problems, though...I just need to be able to replicate it to troubleshoot. I don't think anyone else has reported a similar issue in recent months either, so I'm wondering if maybe there's something on your end that's different. 

Link to comment
Share on other sites

Hey guys thanks for checking in. I first noticed performance issues when trying out dragging things in my app on mobile safari (iPhone 6s Plus). I thought it was something I was doing onDrag. But commenting out onDrag entirely didn't help. I rely heavily on chrome devtools to keep my app performant (60FPS) so I tried various optimizations I could think of, all while capturing performance timelines. Again nothing helped, I continued to get frequent drops in FPS, indicated by the green line drops and red flag warnings in the chrome devtools timeline:

 

f9e06a3b1a030e7543ce4babbb218378.png

 

To determine if this perf hit was caused by something in my app or something in GSAP I created a standalone codepen that does nothing but use Draggable on a single div. The result was the same: frames frequently taking double the time they should be (~33ms instead of ~16ms). Here's a recording of what I'm seeing, in case it helps.

 

I do suspect it has something to do with the "ticks" Jack mentioned. I've reproduced this on a 2013 macbook pro and a 2015 macbook pro. If you hit my codepen and record the timeline you should see the same issue. 

 

Thanks for your help looking into this!

Link to comment
Share on other sites

I was messing with the above codepen example on Windows 7 64-bit and also found it to be smooth as well. I checked both in latest Chrome and Firefox both in private browsing mode, and in timeline frame mode, and saw no jank!

Link to comment
Share on other sites

I'm a bit suspicious that this might be a Dev Tools thing (faulty reporting) because:

  1. According to your recording (and my own test), Chrome's Dev Tools reports multiple "Animation frame fired" events within a single "tick" (or frame). I can't imagine how that's even possible because that's the very thing that defines a tick. So it's like Dev Tools is forgetting to segregate the frames properly (clumping multiple into 1 that looks like it's taking longer...but it's just because it's actually multiple frames). GSAP cannot force the browser to fire "Animation frame" events at-will. GSAP simply listens for when the browser itself does it, and that's when it runs its logic/updates. 
  2. I have seen Dev Tools report things incorrectly before. Here's an example: http://greensock.com/css-performance
  3. Nobody else is reporting any jank...at all. None of us can seem to find it, and with so many people using it in the wild (including the folks at Google), I'd imagine that someone would stumble across it and reach out to us if there was a problem.
  4. Firefox doesn't seem to show this problem in its dev tools
  5. If it was a problem in Draggable where faulty logic was causing a double-tick, I'd expect that to happen consistently (like we'd see the extra logic running constantly) rather than just once in a while the way your recording showed. I'd also expect it to behave similarly in all browsers.

Also keep in mind that mousemove and touchmove events can fire multiple times between ticks/frames, so I wonder if maybe there's a bug in Webkit (or the way Dev Tools reports/interprets things) that sometimes makes it dispatch an Animation frame when it shouldn't. Totally a guess on my part.  

  • Like 3
Link to comment
Share on other sites

  • 2 weeks later...

I guess it certainly could be a bug in the chrome dev tools. It does seem strange (impossible?) for two RAF triggers in one frame. I'll create an issue for them with this example to be sure, and report back here once they've investigated. Thanks!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×