Jump to content
GreenSock

DennisB

GSAP and feTurbulence Mobile Performance

Recommended Posts

I'm currently working on a GSAP project where I ended up using svg filters to simulate a heatwave on an image. For that I resorted to using feTurbulence and feDisplacementMap, based on a forum post on here.

This works excellent on desktop, but when I test on iOS the animation is really sluggish, which is especially apparent when a lot of other elements are animated while the feTurbulence filter is animating.

 

The Codepen supplied here is a simple version with just 2 animations, which shows a clear discrepancy in how smooth it animates on desktop vs mobile, and if it's left running on iOS it ends up refreshing the safari tab and/or removing the animated element, and I've also had it crash the safari tab (Attached screenshot)

 

Any ideas what might be causing that? or how to avoid/work around it?

File.jpg

See the Pen WNzGKrX by dennisbroend (@dennisbroend) on CodePen

Link to comment
Share on other sites

Ah yeah, sorry to be the bearer of bad news. SVG filters are pretty horrific for performance.

 

I've found I can animate them in very short bursts, or on a small area, e.g a small hover effect. But if the animation lasts too long or covers a wide area it's 100% a no-go.

If I were you I'd look into using pixi or webGL/three.js -

Here's a pixi link - https://pixijs.download/dev/docs/PIXI.filters.DisplacementFilter.html

Link to comment
Share on other sites

That is indeed bad news 😦

 

Unfortunately I cant use pixi since this is for a banner which has strict limitations on weight and external calls, and pixi still isn't part of doubleclicks cdn. I could potentially use three.js since that's available, but the heatwave example i found on three was a lot more involved than a quick svg filter.

Link to comment
Share on other sites

This codrops post might be helpful. But yeah - leveraging three.js for a heat wobble on a banner sounds like serious overkill to me. (I did a lot worse in my banner days so no judgement here. I feel sorry for people on low end devices trying to read articles though 🙈)

I'd probably just save out some images with a few different distortions and crossfade between them?

https://tympanus.net/codrops/2016/05/03/animated-heat-distortion-effects-webgl/

Link to comment
Share on other sites

Thanks for the link, it was the same one I found when I first searched around for the effet, it almost seems like there nothing beside that one and the svg filter solution.

 

I do in theory like the idea of having crossfades on different "heated wave" versions of the image, unsure if I can get away with it weight-vise, but it's a good simple solution that should work everywhere.

Link to comment
Share on other sites

You could use one image - load it into different image tags and apply a slightly adjusted distortion filter on each one with SVG. Then jump between them, like a spritesheet?

See the Pen poLEqYg by GreenSock (@GreenSock) on CodePen

Link to comment
Share on other sites

Hah, I kinda miss banner dev. It's a fun problem solving space to try and get the effect you're after while keeping the kb down

Link to comment
Share on other sites

Thats a great idea, and also one I should be able to implement easily.

I´m thinking that maybe I´ll just have 1 image, and then swap out the filter on it to the next in line instead of having individual images, there aren't any glaring problems I´m missing with that right?

 

I dont have a great idea on how to do that in gsap but it could be done pretty simple with a JavaScript function and timer.

 

And yea, sometimes its a fun challenge with banners that feel great when everything aligns, and sometimes it can be a real PITA 😁

  • Haha 1
Link to comment
Share on other sites

Probably less performant than animating opacity as you're updating the DOM each time and getting the browser to repaint/recalculate a filter rather than just changing a composite property.

Link to comment
Share on other sites

Unfortunately that solution still kills the animation on mobile, it gets better the less filters there are, its almost normal animation speed at around 2-3 filters but then the effect is almost too choppy because there's too few steps. So I think I'll just have to disable it on mobile.

Link to comment
Share on other sites

Yep, filters are notoriously VERY demanding on the CPU. It has nothing to do with GSAP. It's a graphics rendering thing with the browser. 

Link to comment
Share on other sites

Ah that's such a shame I hoped if it was just animating opacity on filtered elements it would be better! We tried!

Link to comment
Share on other sites

@DennisB

I don't know what the size requirements are for the project, but if you know your way around writing shaders you could consider using OGL. It's a microscoping webgl at 8kb core and 29kb with utilities and extras if needed. Final build size probably around the lower end of that spectrum.

https://github.com/oframe/ogl

 

If that fits your size constraints but you don't know how to work with shaders I'd be happy to take a look for you since it seems like a fun rabbit hole.

If for whatever reason ogl doesn't work and you still want the effect in three.js I can also take a look at that since it's a neat effect and I to practice shaders anyway.

  • Like 1
Link to comment
Share on other sites

58 minutes ago, Cassie said:

Ah that's such a shame I hoped if it was just animating opacity on filtered elements it would be better! We tried!

It was a great try, and a fun work-around if it had worked, I sincerely thank you for all the help.

 

28 minutes ago, SteveS said:

@DennisB

I don't know what the size requirements are for the project, but if you know your way around writing shaders you could consider using OGL. It's a microscoping webgl at 8kb core and 29kb with utilities and extras if needed. Final build size probably around the lower end of that spectrum.

https://github.com/oframe/ogl

 

If that fits your size constraints but you don't know how to work with shaders I'd be happy to take a look for you since it seems like a fun rabbit hole.

If for whatever reason ogl doesn't work and you still want the effect in three.js I can also take a look at that since it's a neat effect and I to practice shaders anyway.

Wow, OGL looks pretty awesome and a great size to boot. I unfortunately don't have any experience with shaders, so it's a bit daunting, I had a quick look trough the examples and couldnt find anything that fit perfectly or something that would serve as a great starting point. But all the examples looked very neat so I'll definitely save it for some time in the future when I finally have some time to devote for shaders, be it three or OGL.

 

If you're up for it and feeling generous with your time I would love the help, even if it's just a big nudge or a good starting point.

 

Link to comment
Share on other sites

@DennisB

I'm not sure if this helps you or not but: https://codesandbox.io/s/quiet-moon-10ikuq?file=/src/index.js

 

I'll leave it to you to export how you want since I'm not particularly well versed in how to get bundle sizes down. I managed to get it to ~40Kib gzipped.

It's not a perfect turbulence and uses a square pattern to distort. I'll probably go and change that eventually so that it relies more on noise than sin/cos functions. At a low distortion amount it shouldn't be too noticeable.

The size of the element is based on the dimensions of the image used. It's not very flexible in that way but it wouldn't be too hard to make it so if you needed.

  • Like 1
Link to comment
Share on other sites

I didn't realize that it manipulated the entire element, not just the internals. Would've been easier to do that way 😅

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.
×