Skip to content
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

low performance on Firefox Quantum #31

Closed
markomitranic opened this issue Nov 27, 2017 · 3 comments
Closed

low performance on Firefox Quantum #31

markomitranic opened this issue Nov 27, 2017 · 3 comments

Comments

@markomitranic
Copy link

Performance is really bad on FF quantum. Oddly enough, not from the start, it works fine for the first 5s, and then it slows down and kills my CPU.

@madahmani
Copy link

madahmani commented Nov 27, 2017 via email

@scottschiller
Copy link
Owner

scottschiller commented Dec 2, 2017

tl;dr: Ah-ha! 🎉 Set snowStick: false for Firefox 57+ (or hack around it, details follow.)

If you don't mind one missing effect, try setting snowStick: false to improve performance in Firefox 57 (Quantum.) Seems performance suffers when snow "sticks" to the bottom of the window, each additional snowflake's change to position: fixed when it hits the bottom must negatively affect rendering / animation.

fixed is used so that the snow will stay on the bottom while the user scrolls, vs. having to watch scroll events and re-position snow to window height + scroll height accordingly. I realize that while convenient, it's not surprising this may incur a larger expense when animating / drawing active snow.

Alternately, you can hack SnowStorm to set its inner noFixed legacy fallback support to true , I would recommend doing this only for Firefox (version 57+, parse userAgent at your own risk), so SnowStorm will fall back to using position: absolute and watch window scroll and re-position flakes "stuck" to the bottom of the window on scroll. This script was written in 2003 and so it supports IE 6 and others that didn't support position: fixed, way back in the day. (Earlier iOS didn't for a while, either.)

Meandering performance / investigation thoughts follow 🤔

Oh, wow. Checking here on Firefox 57 (Quantum) on OS X Sierra (10.12.6), SnowStorm performance seems to be more sluggish. I'm not sure if this applies also to Windows, etc.

On this quad-core Mac Mini, the main and helper Firefox processes are eating over 100% CPU. ☹️

Safari hovers around 50%, by comparison, but the snow isn't super smooth.

Chrome runs fast and smoothest of the three, and takes about 30% CPU. A performance profile shows Chrome rendering at 60fps, albeit close to the threshold, with 15-17 msec of work per frame on this 2011-era Mac Mini. ;)

SnowStorm is not free, because it involves moving a lot of elements around simultaneously on pages of varying width and height.

It seems Mozilla effectively rewrote Firefox with Quantum, so I wouldn't be surprised if their rendering optimizations (and I'm guessing, here) aren't really geared for constant repainting of small areas of the screen. And/or, something about style invalidation / recalculation being really expensive in this case. Snowstorm causes frequent and specific layout invalidation, and style recalculation on each requestAnimationFrame() callback.

SnowStorm has a useGPU property that determines whether a 3D transform is applied to each snowflake - I don't think that will result in a penalty these days, but it may not be free.

Browsers can also factor in willChange for transform (and/or style left/top) properties and seeing if that helps rendering any. In my quick testing, it didn't appear to make any difference in Firefox Quantum.
https://developer.mozilla.org/en-US/docs/Web/CSS/will-change

A quick hack to switch to translate(*px, *px) seemed to reduce CPU use a bit in Firefox, but that would require a fair bit of refactoring to get the details right. A benefit to the current style top/left/right/bottom positioning is that it can be percentage based, which is a huge convenience - when users resize the window, the snow stays positioned relative to the viewport at all times. Without that, snow would have to reposition on resize.

Testing more in Firefox, even having the snow setXY() function return false (normally this is where top/left/transform get set/updated), I still see 40-70% CPU use. 🔥 (Update: I suspect this is from the piling up of position: fixed snow once it "sticks" to the bottom, hurting performance.)

From what I'm seeing, simply animating snow is quite, er, glacial in Firefox. 👻 🐍 (Boo, hiss.)

I've also neglected to mention <canvas>, which seems like the obvious modern candidate for (hopefully) fixing most of this stuff. It might take some significant refactoring, but would be nice to have canvas as an option for rendering.

@markomitranic
Copy link
Author

markomitranic commented Dec 3, 2017

@scottschiller Wow, thanks for the post, i really enjoyed reading it.

Now, i am not your-level-of-expert on the field of JS animation, but i must admit, i am satisfied that i actually covered most of the proposed solutions while debugging, 👍 for me...

Back to topic, i have realized that it is a quantum specific CPU problem, when i noticed that if i trigger another part of jquery-based animation on that page, snow starts working properly for the duration of that animation. Which made sense, in case that quantum is perhaps trying to scale back on CPU when only snow was running. That is when i tried forcing hardware acceleration and using will change, but to no avail, CPU drop was less than 10%.

Either way, i have also tested some canvas based solutions, i must agree in that they do work far, far better, but on the other hand they need pointer-events to be click thorugh, and while that kind of works with most™ modern browsers, it still seems to still catch all click events for JS... So that is a no-go.

As for snowstick, will try tomorrow morning thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants