-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[p5.js 2.0 Beta Bug Report]: Rendering significantly slower in 2.0 #7539
Comments
After looking into this, I think FES updates might be playing a big role. I tried both sketches with
|
@ksen0 Thanks for looking into it! I think there still could be something going on with the canvas mode. Try cranking the amount of particles up to 10,000. 1.11.3 runs that around 30-40fps, while 2.0 drops down to around 5, even with fes disabled. |
@limzykenneth I did some profiling and it looks like the culprit is I see We talked before about not cloning everything, just doing a shallow copy, and cloning when a property is modified. This is still feasible but will take a bit of an audit of the codebase to make sure we've converted everything. Could be worth it though? |
Also @ksen0 how much of a performance decrease do you see in WebGL over time? I wasn't able to reproduce the same behaviour on my mac, and in Chrome's memory debugger I see the memory wiggling between 74 and 78 mb but not slowly increasing, so I wonder if that's something like the computer getting hot and throttling? Not sure though, let me know if you or anyone else sees something like memory increasing over time! |
So That said, 1.x still runs at 60fps, and the flame graph still shows push and pop taking up most of the time: |
Thanks @davepagurek for taking a look! |
There are a few things that I found that can optimize things a bit more. The other one is the color toString method which uses color.js
@davepagurek I'm thinking is it possible to implement a copy on write algorithm in JS? |
I tried not doing anything fancy yet but just manually copying on write in here: #7543
The other change since 1.x is that shapes are created on a |
Another update: The path thing is actually only different in beginShape/endShape, so the rect performance is likely not different in 2.x. I tried commenting out the p5.Renderer2D.prototype.push = function() {
this.drawingContext.save()
p5.Renderer.prototype.push.call(this)
}
p5.Renderer2D.prototype.pop = function() {
p5.Renderer.prototype.pop.call(this)
this.drawingContext.restore()
} ...but this still maxes out at 20fps for me. If I avoid calling the base renderer's push/pop at all: p5.Renderer2D.prototype.push = function() { this.drawingContext.save() }
p5.Renderer2D.prototype.pop = function() { this.drawingContext.restore() } ...then this brings the frame rate up to match and exceed that in 1.x. I tried replacing the const currentStates = Object.assign({}, this.states); // 18fps
const currentStates = { ...this.states }; // 26fps
// 33fps
const currentStates = {}
for (const key in this.states) {
currentStates[key] = this.states[key]
} It's kind of wild to me that those have such different frame rates. In Firefox it's all equivalent for me, and I still hit 60fps for any of those. Meanwhile, in Chrome, not trying to clone |
I have an implementation of memoized color serialization that seems to work and it doesn't seem to affect memory performance while getting an extra 25-30ms per frame. I'll refine it a bit before pushing it. @davepagurek I was just about to say, I'm also seeing for some reason Object.assign is quite slow in Chrome. Edit: it seems someone saw the same as well: https://stackoverflow.com/questions/78897580/performance-difference-between-chrome-and-firefox-object-assign-spread-adding |
I wonder if we're hitting an issue with the size of the object. I tried commenting out a bunch of properties from Edit: maybe if we namespace a bunch of the properties we can get around this issue? Although if we have |
It could be from what I glance from online that I'm thinking of somehow instead of copying (even shallow copying) the entire state object into the stack, if we can just copy the states that have changed perhaps that can help? Namespace can maybe help and I think the shallower the state object is the better although I'm not sure if it would work since this is pretty weird behavior anyway. |
Here's one more demo that uses some |
Ok it looks like, without per-particle fills, we're back to equivalent performance! https://editor.p5js.org/davepagurek/sketches/XAQwXN6OR To summarize, the updates I had to include:
|
@davepagurek Nice, do make a PR and I can try it out locally as well. I have the color serialization one almost done, just want to try some other optimization and I'll do a PR for that tomorrow as well. |
I'm going to close this one for now since we've addressed the main things. We'll release a new beta version soon, and then feel free to make new issues if more perf issues come up! |
Most appropriate sub-area of p5.js?
p5.js version
2.0.0 beta 2
Web browser and version
Chrome 132.0.6834.111
Operating system
MacOSX Sequoia 15.2
Steps to reproduce this
Both webGL and canvas renderer performance seems to have dropped between 1.11.3 and 2.0.0 beta 2 significantly. In the attached sketch, I try to draw 1000 particles. In 1.11.3, I'm able to achieve a smooth 60fps. In 2.0, I barely crack 20fps with webGL, 40fps for canvas. In fact in 1.11.3 I can render 3500 particles in webGL still at 60fps. You can comment between the two libraries in the index.html file.
There are some other issues mentioning webGL losing perf from around a year ago #6743 , I didn't see anything more recent but since this seemed like (to me) a common use case it felt worth bringing up again, especially since the canvas renderer appears to be significantly slower as well.
Steps:
Snippet:
webgl: https://editor.p5js.org/aferriss/sketches/_x59zc5AH
canvas: https://editor.p5js.org/aferriss/sketches/lFcjKYZKM
The text was updated successfully, but these errors were encountered: