Jump to content
Search Community

Measuring animation performance

imdavidmin test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Hi,

 

Is there a special / approved way of measuring animation performance on the client? I would like to measure if the animation has lagged vs specified duration, or if greensock was being clever under the hood and skipped frames to optimise the animation. 

 

Currently I'm using a onComplete call within gsap.to to print the end of animation time, and comparing that to a time from just before the animation was called.

 

This way I'd be able to turn off animation effects automatically across the site based on some initial test, for slower performance devices. One extreme edge case was when I opened a web app in a virtualised macOS machine that did not have GPU passthrough, so simple transform animations would freeze the entire machine. Would avoid having these problems by running a small transform animation test for a few ms duration to see how it performed, then decide on the animations for rest of site.

 

EDIT: The timestamping method doesn't work well for performance measurement - testing shows the elapsed ms from before gsap.to() to onComplete call could be less than the duration specified in gsap.to().

 

EDIT2: For anyone having the same experiment with a virtualised machine for dev environment, the guest OS / Safari doesn't freeze or drop frames as per the fps measuring function given by Jack below. It's likely about how VMware renders the graphical output of the guest OS back to you on the host OS that freezes / drop frames.

Link to comment
Share on other sites

My performance testing lies very much in the 'does it look jerky' and  'is my laptop fan making noise' camp.

You can test FPS using gsap.ticker - maybe that helps? Although, it's good to be aware that it's often not a hugely helpful metric

 

var fps = gsap.ticker.frame / gsap.ticker.time;



I think this is probably a good question for Jack though -  @GreenSock

  • Like 1
Link to comment
Share on other sites

19 hours ago, imdavidmin said:

Is there a special / approved way of measuring animation performance on the client?

 

No, and trying to do such tests is very error prone. Let's say you run a test and determine it's slow. Great, but you don't know the reason it's slow. It could be something running in the background on the user's computer and not the animation. And that background process that is hogging all the computer's resources might stop right after you run your test.

 

I usually base my performance assumptions on the user agent and screen size. If I can determine it's a mobile device, then I might need to tone down or turn off some of the animations.

 

19 hours ago, imdavidmin said:

One extreme edge case was when I opened a web app in a virtualised macOS machine that did not have GPU passthrough, so simple transform animations would freeze the entire machine.

 

I've never seen an entire machine freeze. Will that happen if you use a css transition/animation with 3d transforms?

 

  • Like 2
Link to comment
Share on other sites

3 hours ago, OSUblake said:

I usually base my performance assumptions on the user agent and screen size. If I can determine it's a mobile device, then I might need to tone down or turn off some of the animations.

Extreme same here. I animate a lot less on mobile.

It's also better from a UX point of view, people on mobile sites are usually on the go and just after some information - no need to mkae everything whizz around.

  • Like 1
Link to comment
Share on other sites

1 hour ago, Cassie said:

It's also better from a UX point of view, people on mobile sites are usually on the go and just after some information - no need to mkae everything whizz around.

And then there is me, who is animating everything visible for my mobile site. 90% of the entire code is for animating elements, no regret tho . 

  • Haha 2
Link to comment
Share on other sites

5 hours ago, OSUblake said:

 

No, and trying to do such tests is very error prone. Let's say you run a test and determine it's slow. Great, but you don't know the reason it's slow. It could be something running in the background on the user's computer and not the animation. And that background process that is hogging all the computer's resources might stop right after you run your test.

 

I usually base my performance assumptions on the user agent and screen size. If I can determine it's a mobile device, then I might need to tone down or turn off some of the animations.

 

 

I've never seen an entire machine freeze. Will that happen if you use a css transition/animation with 3d transforms?

 

Either way we are making assumptions - of course we can use screen size to turn off for mobile, but some mobile devices are good enough to run the animations. Having some way to measure, even if not guaranteed accurate, just adds one more data point to make a decision on whether to turn off animations or not. 

 

It's a virtual machine, so it's very much a special edge case that is unlikely to ever happen to real users. Because there's no GPU pass through, even switching windows animation by the system ramps up CPU usage to near max for a second. A more realistic scenario is indeed on a lower end mobile device or on a really old machine. 

1 hour ago, Cassie said:

Extreme same here. I animate a lot less on mobile.

It's also better from a UX point of view, people on mobile sites are usually on the go and just after some information - no need to mkae everything whizz around.

Agreed on reducing animations on mobile, but some minimally animated elements still are important UX wise to make it feel more like a native app. But of course, that can't come at the price of lagging UI, which will then be more harm than benefit.

Link to comment
Share on other sites

5 hours ago, imdavidmin said:

Either way we are making assumptions - of course we can use screen size to turn off for mobile, but some mobile devices are good enough to run the animations. 

 

Oh, I didn't mean it that as a hard rule to turn off animations on mobile. Just something to consider. It all depends on what you're doing.

 

5 hours ago, imdavidmin said:

Having some way to measure, even if not guaranteed accurate, just adds one more data point to make a decision on whether to turn off animations or not. 

 

You could have a toggle button, kind of like how you see dark and light theme toggles, or something like accessibility control where control animations, giving the user the most control.

 

image.png

 

 

 

 

 

 

 

  • Like 1
Link to comment
Share on other sites

  • Solution

Yeah, you need to be very careful because there are a lot of factors:

  1. Startup spike - when a page loads, the browser has to spend a LOT of resources on various things like layout, rendering, rasterizing, layerizing, executing the JS and looking for the best ways to optimize it (identifying "hot" functions), etc. So if, for example, you run some transform animations for 500ms on initial load, for example, it may artificially seem like it's a slow device because the browser is so busy doing all those other tasks, but those will settle down shortly and the JS/animations may run buttery smooth thereafter. Be careful about a simple gsap.ticker.frame / gsap.ticker.time because that doesn't compensate for the initial drop in FPS when a page initially loads and the browser is doing all that startup processing. That initial hit may contaminate the average. In other words, maybe it runs at 0.5fps for the first 1.5 seconds, and then 60fps thereafter, but if you check the fps at the 2-second point, it'll look pretty terrible, like 2fps or whatever. If you then shut off animations because you think it's a slow device, you totally miss the fact that it was actually starting to run at 60fps right before you measured. 
  2. Refresh rate (hz) - Most devices target 60fps but some may run at 30hz, and others at 120. So if the device only refreshes its screen at 30hz, the browser will only run requestAnimationFrame() 30 times per second, thus if you have code that's verifying against a 60fps target, that device may "fail" even though it's not maxing the CPU out at all and is running perfectly "smooth" (according to its own specs). 
  3. Competing resources -  like Blake said, your test may happen to run at the very moment the device has a CPU spike due to some other process like pulling in and parsing data via Wi-Fi or performing a backup routine or some other expensive app is open in the background. 

I don't think there are any foolproof, reliable ways to calculate what you're asking in a very short amount of time but here's a helper function Just whipped up for you that might be helpful: 

function testPerformance(config) {
	let fps = config.fps || 45,
		duration = config.duration || 1,
		testElements = [],
		i = ("elementCount" in config) ? config.elementCount : 5,
		runTest = () => {
			let startFrame = gsap.ticker.frame;
			gsap.to(testElements, {rotation: 360, x: 100, y: 100, duration: duration, onComplete: () => {
					let measuredFPS = (gsap.ticker.frame - startFrame) / duration;
					testElements.forEach(el => el.parentNode.removeChild(el));
					if (measuredFPS < fps) {
						config.onFail && config.onFail(measuredFPS);
					} else {
						config.onSuccess && config.onSuccess(measuredFPS);
					}
				}
			});
		},
		onLoad = () => config.delay ? gsap.delayedCall(config.delay, runTest) : runTest();
	while (--i) {
		let el = document.createElement("div");
		document.body.appendChild(el);
		testElements.push(el);
	}
	gsap.set(testElements, {position: "absolute", visibility: "hidden", width: 10, height: 10, top: 0, left: 0, x: 0}); // remove elements from document flow and make the invisible
	(document.readyState === "loading") ? window.addEventListener("load", onLoad) : onLoad();
}

Usage looks like: 

testPerformance({
	fps: 45,         // minimum frames per second
	duration: 1,     // how long to run the test (in seconds)
	delay: 0.5,      // time (in seconds) between page load and test start (to give the browser time to settle down)
	elementCount: 5, // number of elements to animate during the test (rotation, x, and y)
	onSuccess: fps => console.log("success", fps),
	onFail: fps => console.log("fail", fps)
});

You could crank up the elementCount to a super high amount if you want to see the fps drop. Not that you'd do that in your "real" project. 

 

Does that help? 

  • Like 6
Link to comment
Share on other sites

17 hours ago, OSUblake said:

You could have a toggle button, kind of like how you see dark and light theme toggles, or something like accessibility control where control animations, giving the user the most control.

Yep that's also the plan. The performance measuring would help to establish the default setting.

  • Like 1
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.
×
×
  • Create New...