Jump to content
Search Community

Perfs amelioration on multiple stroke animation

alaric test
Moderator Tag

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

 

Hi everyone,

 

I recently made an animation which recently had quite good feedback from the codepen community (https://codepen.io/alaricweb/pen/vWxPyp ). I too feel like there is something very cool in this animation but the perf are really bad on mobile. 

 

I don't blame GSAP for that it's pretty amazing already to be able to have such result with that few lines !

 

But now i want to be able to use this kind of animation in a real website but with that impact on perf it's not imaginable.

 

I don't think i can improve the perf significantly with SVG only, if i animate less stroke, the result won't be as cool.

 

So i'm currently looking to an alternative to have the same animation but with improved perfs !

After some research i'm starting to think that animating inside a canvas is my best option. 

 

I feel like PixiJS could be a good option with some tricks, maybe threeJS too.

 

I saw @OSUblake  pen in which we can see that he is using GSAP morphing inside the canvas and the perf are just incredible compared to mine.

You can see for yourself here.

 

See the Pen oWzVvb?editors=0010 by osublake (@osublake) on CodePen

 

 

 

So if any of you know if it's possible to have my animation inside a canvas and with what method i could try to make it better i'd be thankful for some guidelines.

 

Alaric

 

  • Like 3
Link to comment
Share on other sites

Hi @alaric

 

You pretty much hit the nail on the head here.

 

9 hours ago, alaric said:

I don't blame GSAP for that it's pretty amazing already to be able to have such result with that few lines !

 

The performance problem isn't related to GSAP, but how the browser handles rendering. It's amazing to see how you can pull off a very complicated animation with only a few lines of code, but that convenience comes at price, usually in the form of degraded performance.

 

When using DOM elements, you're pretty much going to be at the mercy of the browser when it comes rendering performance. With canvas, you're largely in control of how and when things get rendered, so performance might be better. However, the freedom that canvas gives you makes using it more complicated and can work against you if you're not careful.

 

Here's a really good video that goes over the pros and cons of using the DOM and canvas.

 

 

 

With a little work, you can improve the performance with canvas. PixiJS is a good choice for a lot 2d animations, and that's what I typically recommend, but for this particular animation I don't think it's going to be of much use. Drawing paths with PixiJS is somewhat limited, so you'll need to use the drawing commands provided by the native canvas api

 

I'll rework your demo later on, and see if I can get performance to improve using canvas. I'm not sure how much performance will improve as there are bunch of unique paths in your SVG (941). The paths are fairly simple, but rendering that many paths with canvas still might be pretty intensive. 

 

In the meantime, if you've never used canvas before, here's a couple good places to start.

https://www.kirupa.com/canvas/index.htm

https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial

 

I also wrote some tips on using canvas here.

 

And here's some other canvas libraries that might be worth checking. 

 

  • Like 3
  • Thanks 1
Link to comment
Share on other sites

I checked some of your links and it's helping a lot !

 

I think I'll start with canvas and gsap only to experiment a bit and then try with some of thoses impressive canvas libraries.

 

I'll post each one of my experience here during the week so anyone will be able to have a look on the perf improvement or not of each method.

 

Thanks a lot @OSUblake for your help.

 

 

 

  • Like 1
Link to comment
Share on other sites

2 hours ago, alaric said:

I think I'll start with canvas and gsap only to experiment a bit and then try with some of thoses impressive canvas libraries.

 

I'll post each one of my experience here during the week so anyone will be able to have a look on the perf improvement or not of each method.

 

That's a good idea! Get out of your comfort zone, and start experimenting.

 

I don't think canvas is particularly difficult, but it requires a completely different mindset than when you are working with the DOM. Using a canvas library can make the transition easier, but I think it's still a good idea to understand how to do stuff without a library.

 

One of the coolest things to look forward to if you know canvas is the CSS Paint API (explainer), which is scheduled to land in Chrome early next year. With this API, you'll be able to create and animate your own custom CSS properties.

 

This will open up so many possibilities when it comes to creating visual effects. For example, instead of adding, animating, and then removing multiple elements to create a Material Design ripple effect on a button, you'll be able to simply paint the ripples on the button using a rendering API based on canvas. 

 

  • Like 4
Link to comment
Share on other sites

Hi all !

 

First of all thank you all for your positive feedbacks about my pen !

 

I played a bit with canvas today and just tried an experiment by forking one of @OSUblake pens.

 

My goal was to see how the CPU deal with multiple stroke animation.

I started from @OSUblake pen here in which he draw a path inside a canvas and animate the ( i think it's at least an equivalent ) stroke-dashoffset property .

here is his pen 

 

See the Pen qNJvjY?editors=0010 by osublake (@osublake) on CodePen

 

 

Below is my fork with 100 path

 

See the Pen ?editors=0010 by alaricweb (@alaricweb) on CodePen

 

 

It's probably too soon to draw any conclusion but i think canvas may render my initial pen. The perf may not be very different but it's worth trying.

 

I'll try to animate the same amount of stroke in svg while displaying fps to have a better comparison between the two methods.

 

If anyone notice something prevaricating the comparison please don't hesitate to notify me.

Also if you have any idea that could help in any way feel free to jump in the discussion.

 

Thank you,

Alaric

 

 

  • Like 1
Link to comment
Share on other sites

There you go! Now lets add in some optimizations.

 

Use for/while loops

Avoid using array methods like forEach when doing anything related to rendering. Yes, it's nice and convenient, but it's much slower than a for/while loop. Modern JavaScript provides a simpler way to create for loops if you don't need to increment a value, like for an index.

 

// This is the same...
for (let path of paths) {
  console.log(path);
}

// ...as doing this
for (var i = 0; i < paths.length; i++) {
  console.log(paths[i]);
}

 

 

Use an opaque canvas

This is an option when creating the canvas context that will make the canvas opaque. This will improve performance when drawing transparent content as the browser doesn't have to create a composite with content that might be behind it. By default, this will make your canvas black, so instead of clearing the canvas, you just fill it with something like a color or image.

 

var context = canvas.getContext("2d", { alpha: false });

 

 

Use Path2D
Path2D is an incredibly powerful new feature. It allows you to create reusable path objects, and works with SVG path data and SVG matrices. Once you create a Path2D object, it stores all the drawing commands as vectors, so you don't have to keep calling the same drawing commands over and over. And since everything is stored as a vector, it's scalable. 

 

Here's a modified version of what you did with those optimizations. I also added some rendering complexity to see how it would perform using different colored strokes with transparency and blend modes. 

 

See the Pen QOmLvz?editors=0010 by osublake (@osublake) on CodePen

 

 

I'm still looking into some other rendering techniques. The slowest part by far is drawing the strokes. Doing the fills can be doing rather quickly. I'm curious about your SVG. How did you make that? It seems like it uses a lot the same shapes, not necessarily the size, but the overall shape with all the little arcs. That means there might be a way to further optimize rendering by using the same shape/path for different parts of the bike.

  • Like 5
Link to comment
Share on other sites

Hi @OSUblake,

 

First of all thanks a lot for all those informations and this amazing pen !

 

Unfortunately I've a bit more work than what I expected this week and I lack time to fully understand what you did there.

 

I'll take the time to understand well how you improved the perfs and what you're using before posting another pen. 

 

For your question about the svg I didn't really made it. It's a vector illustration from shutterstock that I edited on Illustrator before exporting it to svg.

But I think you're right when you say that most of the shapes are similar.

 

It could be a good idea to just reuse one model but with different scale / position / fill it it benefits the perfs.

 

If it helps I could redo the svg as soon as I can but this time re-using the same shape as often as possible.

What do you think of that ?

 

Thank you again for all the time you invest, i really appreciate it.

I'll try to advance on this as often as I can.

  • Like 1
Link to comment
Share on other sites

Hi everyone !

 

I've been quite busy recently but I found some time to improve the perfs for this animation and create something more usable in production.

 

For those interested in seing the code you have a public git repository here DELETED

Since it's from an article in Codrops I can't share a codepen of it.

 

The biggest improvement is in the SVG itself. I drew my own and went from 941 to 386 paths in total for a similar visual effect !

Reducing the amount of path was primordial as it has been suggested here.

 

Then we came to the conclusion that it's not the kind of animation you leave animating forever as in my original pen.

So we leave it animating just long enough to enjoy the effect and then we freeze it.

You can see the result here https://tympanus.net/Development/AnimatedStrokes/

 

There may be some possible improvement to make by using the canvas technology.

But right now I personally think that it's something usable and relatively performant enough :)

 

If I manage to do something with a canvas I'll come back here to share it with you !

@OSUblake Thank you for the help, I'll try to finish this experiment !

 

 

  • Like 2
Link to comment
Share on other sites

Hi @Sahil

 

I'm quite embarrassed here .... 

 

I thought the responsibility was on the end user to not resell the plugin without purchasing his own license and mentioning that to them...

 

Since I used this in my previous codepen animation which is also public without any problem I don't see the difference ( since they can get the plugin from there too unless i'm wrong ).

Isn't a mention on the repository enough ? Or if i add an alert on demo launch of the repo with a message about the license ?

 

Thanks for your answer.

 

Alaric

Link to comment
Share on other sites

Howdy, @alaric. Congrats on the codrops article. Nice work!

 

As for the members-only plugin, yeah, we prefer that folks not share that in public repositories or in tutorial downloads because it just makes it way too easy for people to snag it without ever getting a membership of their own. That hurts the funding mechanism that allows us to do what we do. I'm sure you didn't intend that, and we totally understand that it was just an honest mistake. 

 

Our entire business model relies on the honor system, so it's not the end of the world that you shared it - we've never threatened to sue anyone nor do we aggressively police licensing violations. That's not "how we roll". We extend a lot of respect to our users in the hopes that it'll be reciprocated and generally we've found that to be true. 

 

The versions that we have on codepen contain some special code that ONLY allow them to work on the codepen domain, so people can't just grab those and use them on their own site. Well, they could if they expend enough effort to get through the obfuscated security logic, but at least it's a speed bump and it ensures that people know that they're supposed to get a license of their own. If they're intent on ripping us off, it's not very difficult. But the danger in folks including the "real" versions of the members-only plugins in their repos is that other people may simply assume that those plugins are open source and free to use. So in that case, we end up with people violating the license unintentionally and not paying for a membership they didn't even know existed. See what I mean? 

 

But again, don't feel too bad. I'm sure you'll be mindful of this in the future. We appreciate you sharing your knowledge with people out there and creating projects that illustrate the cool stuff that's possible with GSAP. 

 

Happy tweening!

  • Like 3
Link to comment
Share on other sites

Hi @alaric

 

Nice job on Codrops article. I'm curious, did they ask you to do that, or do you have to ask them if you want to do an article?

 

On 12/5/2017 at 9:45 AM, alaric said:

There may be some possible improvement to make by using the canvas technology.

 

I'm still kind of curious to see how it would perform using canvas. The problem with SVG is that is scalable. That means everything needs to be recalculated when it changes. For every path, it has to calculate the geometry of the fill, the geometry of the stroke, and then draw those shapes on a bitmap so it can be rendered to the screen.

 

But in your animation, the stroke is the only thing that is actually changing. The fill doesn't. You're just changing its opacity, which doesn't affect its geometry. That's a huge optimization that could be made with canvas. You can convert the fill to a bitmap, and keep reusing that instead of drawing a new path for the fill on every animation frame. In theory, that will reduce the amount of time the browser spends on doing path operations in half.

 

If I get some free time, I might mess with your new SVG. The markup looks really clean, which should make it pretty easy to convert into a canvas animation.

  • Like 2
Link to comment
Share on other sites

Hi @OSUblake

 

Thank you ! They contacted me after seeing my initial bike animation ( the one on top of this topic ).

 

I understand your theory and it seems like a good idea !

 

Feel free to reuse my SVG as much as you want ! I don't feel like I'm able to contribute enough for the canvas part because of my current skill on this technology.

So if I can help by editing the SVG with illustrator tell me.

I remember you suggested reusing as much as possible the same paths. I tried that a bit but gave up half way in this new SVG because this kind of design was new to me and the delay was short.

 

Would it help if I send you an edited SVG using a set of path that only differs in scale / position / rotation ( with a list of the "template" paths ) ?

 

Let me know, I'd love to help !

 

  • Like 2
Link to comment
Share on other sites

I think your current SVG might be doable now that's it's down to ~300 paths. I was worried about trying it with 900 paths because converting a path to bitmap comes at the cost of memory. If you create too many bitmaps, you can run out of memory, causing your app to crash, particularly on mobile devices.

 

I should have some time to play around with this later tonight, and will post back later.

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