Material-ui: [Core][Perf] General performance optimizations needed

Created on 10 Nov 2014  Â·  51Comments  Â·  Source: mui-org/material-ui

Slow as hell on rMBP / Safari. It provides very bad user experience.

Anything we can do about it?

performance

Most helpful comment

@nathanmarks do you happen to know what the timeline is looking like for 0.16?
I would love to use this library, but it's extremely slow on my phone

All 51 comments

Please be more specific. What exactly appears slow to you?

This is a pretty general thing for retina macbook pros. They aren't really beefy enough (at least, in my experience on a 2013 rMBP with maxed out spec options) to handle smooth CSS animations with the DPI they are pushing. @paulmillr, try opening the demo on an external 1080p screen and clicking around - you'll see its much smoother.

This is a MBP internal problem primarily.

Everything is slow. Animations, transitions etc.

Same thing on iPhone 6+. Not MBP-only.

I think that promoting elements to their own layers could help in general. I'll try to check it.

Thanks Rafa!

@rafayepes Keep in mind that promoting elements to their own layers is not a silver bullet, since too many layers incurs its own performance problems.

It is quite slow on ipad as well. I tried material angular https://material.angularjs.org/ , seems very responsive.

The performance (especially on mobile devices) is rather poor.

Compare for example the click effect for the buttons vs. Angular's Material component. I made a short recoding of me rapidly clicking the button component.

Material UI:
http://cl.ly/1b0B3L1y420c

Angular Material:
http://cl.ly/0k3i3a2t1d2P

The effect is slightly delayed (especially on mobile devices). Also the is UI not responsive during the animation.

What is the possibility of adding fastclick.js as a dependency? The 300ms delay with the touch events is the only speed issue that I'm encountering on iOS Safari.

I don't think it's so much about fastclick, I see the same problems on both mobile and desktop.

Performance will be better in JavaScript + CSS, because most of these animations are stateful and require communication with the JS thread.

http://davidwalsh.name/css-js-animation

Edit: "Angular Material" does the animation using JS + CSS (rather than keyframes, material-ui)

Demo Source

The ripple animation is divided into 2 events on those projects (onMouseDown & onMouseUp). You can see this by clicking and holding down the buttons on polymer and angular material.

In contrast, Material-UI is executing the complete animation on a single click. We could look into separating the ripple animation into 2 events, but I'm not sure how that will play with onTouchTap. It requires more investigation for sure.

Hi there. Firstly I would like to thank all contributors for the great work. Thanks for sharing this with the community.
I have tested the examples on Moto X, Moto G and Ipad 3 (iOS 8). The example seems OK (not super fast) on Android devices, but quite slow on Ipad 3 (I see a lag between the actual touch and the redrawing on the screen). By reading the comments I am not sure the way react works will allow it to have the same performance as seen on Angular Material, but I love React so much more than I love Angular! :)

The question is: Do you guys believe React may be able to deliver the kind of performance for this kind of components on either Android and iOS? Or is it impossible to achieve a much better performance (on this scenario) because the way React internals work?

If there is any test I can do to help investigate that, just let me know. I am still learning React, so I have limited knowledge, but I can help testing if you guys need.

Regards

I know they are two different things, but this demo (based on an older version of React) feels much smoother.
http://petehunt.github.io/react-touch/

I don't think this has anything to do with touch events being slow, does it? The problem seems to be that only one Ripple element is animated in a Ripple component at a time. If we could maintain an array of ripples, pushing one on click/tap and removing it on animation end, that would make the animation look responsive.

Disclaimer: I'm not an expert in this library (or React, for that matter) but I will look into implementing this in the upcoming weeks unless someone else who agrees does so first :smile:

I've reworked ripples as @glifchits suggested. Ripples are now triggered onMouseDown & onTouchStart. The current version on master has this change in place, but it'll go up in the next release.

@jfbaro @paulmillr can you guys test it again with this changes? I'd love your feedback.

I was testing the demo website from my nexus 6 and is a bit lagged...

Specially the sliders, menus and tabs.

@krik thanks for video, it Does seem whacky on Mobile. I opened demo page on iPhone, and it seems like the buttons are getting clicked twice...

Hi...maybe naive question here.

What is the purpose of recursive settimeout call to _pulsate in focus-ripple?

On an older android (Chrome on Samsung S3), I noticed that for any list (using ListItem) the scroll bar would flash over and over, as if the page was resizing a bit, again over and over.

On desktop, if you inspect a list you can see in Chrome all the ripple elements flashing in Dev Tools, one per ListItem. You can see this here inspecting a row: http://material-ui.com/#/components/lists

here is the call: https://github.com/callemall/material-ui/blob/b755b19a6652f9b484e0211f1c186b5acae6cfb5/src/ripples/focus-ripple.jsx#L107

If I disable this line locally (comment out), this scroll bar flashing effect goes and the list is a bit smoother.

But I don't see any noticeable UI change disabling this recursive pulsate.

Anyone understand the need for the recursive settimeout pulsate call?

@michelob This is to animate the keyboard focus ripple. I recently added a fix that would only render focus ripples if the component had keyboard focus - seen here: https://github.com/callemall/material-ui/commit/0f61f9e081c99137cd6f8cc4e29b282a9a9d7045. This fix will go up in the next release, and the problem you're describing will go away.

@hai-cea nice!

I also see 10.2 is up. I've taken that and see improvements especially with leftnav. Thank you!

Most of demos are slow in Chrome

@hai-cea

  • In 0.11.1, the ripple animations fire twice on my mobile safari devices.
  • In 0.10.4, and as reported above at various moments, ripple animations are slow to fire.
  • Interestingly, in 0.10.1, they are silky smooth and work fine on my iDevices.

I am using the exact same code for my application, only switched out versions. For now, I'm reverting to 0.10.1 but wouldn't mind seeing a more permanent solution. ;-)

(edit: included 0.11.1 test)

@quangv Found the cause of this issue pretty quickly. TouchRipple listens to both onTouch and onMouse events. Problem is that Mobile Safari usually fires onMouseDown after onTouchEnd. This usually, but not always, generates two distinctly different ripples.

To prevent this, there is some logic in TouchRipple's start() function to prevent double firing of these CircleRipples, but it doesn't function well on Mobile Safari:

    if (!isRippleTouchGenerated) {
      for (var i = 0; i < ripples.length; i++) {
        if (ripples[i].props.touchGenerated) return;
      }
    }

A quick timeline of what happens (most of the time) on Mobile Safari:

  • touch event fires; start() is called on the TouchRipple. CircleRipples are added in an immutable array into the components' state. Each CircleRipple obj has a prop containing "isTouchGenerated" which is, I assume, supposed to prevent these "double" ripples.
  • the ripple effect finishes a bit later and TouchRipple's end() function is called. This removes the CircleRipple array from TouchRipple's state.
  • mobile safari fires onMouseDown. TouchRipple's start() function checks for existing ripples by checking the TouchRipple's state for an array of CircleRIpples, but since these have already finished, none are found. A new set of CircleRipples is then generated, causing the "double" ripple effect.

I worked around this for now by calling e.preventDefault() at the end of start() but this is of course just a stopgap solution. I can't commit the time for a proper fix right now so just wanted to share this.

_Note that this is a little trickier to debug due to event propagation not working well while using breakpoints._

Edit: As I expected, e.preventDefault breaks some of the other components, most notably the Toggle component which relies on onChange being fired. Will provide a different workaround as time permits.

is this still an issue? Seems ok on iphone 6. however, the ripples are firing twice, i assume because the second time is ontouchup

same problem still..

@arush You're right; firing twice is an issue on iOS, see my previous posts. I have another quick fix running but it is not applicable for general production purposes outside our use cases, so I won't run it through a PR at this time.

@hilkeheremans did you manage to figure out why 0.10.1 is so much smoother?

@hilkeheremans FYI I have submitted a pull request to fix the issue of double ripple (due to compat mouse down firing, as you say).

for me it was so slow, that i have implemented some components myself. If you would turn on chrome's dev option: flash on redraw, you will see, that most animations are causing to redraw random stuff that are not connected to clicked on. I've noticed flashing on left top conner all the time with material-ui.com text fields and some other animated elements.

You can see slowness causes in action: https://www.youtube.com/watch?v=S9bciD20u8Q

Just don't make your animations cause global redraws and it will already be a lot faster. At least it helped me. You can see production-ready app with material-ui and react here: http://arcchat.com/
it's fast now.

Main thing is to animate things without page repaints, just open dev console (chrome) and click esc. select "rendering" and check "enable pant flashing"

image

and then go test your site's animations. Remove all the things that cause repaints and it will be a lot faster. Of course, if you have less DOM elements, you should not "feel" anything, but when i do have some DOM elements + several iframes and those iframes begin to repaint because user clicked some text field or icon with ripple it becomes an issue.

Here's live demo. Go to docs:

http://www.material-ui.com/#/components/text-field

enable that flashing option and click on text field, click somewhere else, click on text again. Notice flashing on left top corner? Waaay out of text field? That flashing makes some DOM elements to repaint and that causes slowness for all app.

I really like this lib, it's best what i could found. It had terrible documentation, but i see it's getting better now. I had no time to submit PR for every issue i had on the way, just cloned copy of whatever newest version was available (it happened to be v0.13.4) and built with it, so i can't really share my code, it's coupled with my app. You can see some code here: https://github.com/callemall/material-ui/issues/3295 with my fixes for dialog component.

I've been attempting to use react and material-ui in an Electron (chromium) based app to remake my player with better tech.

My player renders the video on a <canvas> with .requestAnimationFrame() at 24 fps (usually, depending on the video) and whenever I click any material-ui element and a CSS animation begins the FPS of the entire app drops like it got hit by a bomb.

I've done numerous tests by overwriting the transition effect of the entire app to none, tested using the material-ui elements again (this time with no css effects) and the issue was gone.

Decreasing the transition FPS with steps also improved the performance a lot, but overwriting transition for the entire app is definitely not a usable solution..

I also found a video that largely resembles my own findings when testing with a .requestAnimationFrame() FPS meter and Chrome's internal FPS meter:
http://greensock.com/css-performance

The article is vast and it includes comments by @paulirish (from chrome, I'm really sorry for pinging you but I'm also hoping that you might be the right person to shed some light on this 1.5 year old performance issue on an amazingly popular CSS framework).

The issue (as the author of that article mentions) is related to CSS animations on nested elements:

When nesting could be avoided, pure CSS animation of only transforms did appear smoother on webkit browsers under heavy pressure and it was basically indistinguishable from optimized JS animations under all other levels of pressure.

Thank you for all the great work your doing here, I really hope to see the animations optimized for performance at one point, as in it's current state it is unusable to me in a video player as stuttering and freezes lead to a very bad UX.

@jaruba if you want to capture a timeline recording, i'd be able to spot what's happening a lot easier: https://www.chromium.org/devtools/capturing-a-timeline-trace

@paulirish definitely!

http://powder.media/timeline_recordings.zip

The archive includes timeline recordings of various actions, some of which (like clicking a toggle switch) should obviously not create any stutters, although all do, some more then others.

Thanks so much for answering, and sorry again for dragging you into this.

I'm also a bit baffled by the mixed signals I am getting about material-UI in a new project. It is by far the most popular material framework specifically for React (17k + stars) yet I keep running into people complaining about performance being sub-par. Is the performance only an issue in specific cases where for example more than x amounts of a specific component is used with animations, cases that might be avoided? In that case it might be handy to have some kind of 'use material-ui for these kind of applications but avoid it for that kind of applications because of the performance issues that will occur" ?
Because it would seem strange that a framework with performance issues would be so popular?
Anyone care to shed some light on this?
The framework looks great but I would like to prevent having to switch over to a different framework because of performance issues half-way in a project.

Kind regards,

@jeroennelen wait for 0.16

@nathanmarks do you happen to know what the timeline is looking like for 0.16?
I would love to use this library, but it's extremely slow on my phone

I really loved Material-UI the moment I came across it and immediately decided to try it out for my first React-based app. Unfortunately, I went too far with it, before discovering the performance issues around the List component. When the page has more than 30 odd items in the List, the performance lag starts to become noticeable, particularly on the mobile (iP6+). Above 100 items, the list becomes almost unusable on the mobile.

The performance problem exists even if I'm using a simple grid of 50 Buttons (5 buttons x 10 rows). It's a bummer that such a stunning framework has huge performance issues.

@JeroenNelen if an application relies on lists or a grid of components with more than 50 items, stay away until the performance issues are fixed.

Moreover, the touch tap still fires 2 events (as discussed earlier on the thread). In my application, tapping on the first list item brings up another list. But due to double firing of events on the first tap, it records a click on the second list also and the entire flow messes up.

I'm really hoping that 0.16 would address some of these issues. Looking forward to it.

now I use this lib to launch faster and then replacing elements with basic
versions that I write myself to have same look and a lot less event
handlers and dom elements. buttons, switch, table, input, icon, fab were
already redone. this is great framework, but please check performance of
all elements.. add some CSS file, it's OK to use CSS when it's performance
is so much better e.g. for such events as hover. you don't have to support
old crappy IEs anymore, you can do a lot with CSS faster then JS, leaving
JS busy with all react stuff

On Jul 30, 2016 08:08, "deepfriedbrain" [email protected] wrote:

I really loved Material-UI the moment I came across it and immediately
decided to try it out for my first React-based app. Unfortunately, I went
too far with it, before discovering the performance issues around the List
component. When the page has more than 30 odd items in the List, the
performance lag starts to become noticeable, particularly on the mobile
(iP6+). Above 100 items, the list becomes almost unusable on the mobile.

The performance problem exists even if I'm using a simple grid of 50
Buttons (5 buttons x 10 rows). It's a bummer that such a stunning framework
has huge performance issues.

@JeroenNelen https://github.com/JeroenNelen if an application relies on
lists or a grid of components with more than 50 items, stay away until the
performance issues are fixed.

Moreover, the touch tap still fires 2 events (as discussed earlier on the
thread). In my application, tapping on the first list item brings up
another list. But due to double firing of events on the first tap, it
records a click on the second list also and the entire flow messes up.

I'm really hoping that 0.16 would address some of these issues. Looking
forward to it.

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/callemall/material-ui/issues/42#issuecomment-236343340,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ACm3Jsnpjuz0vWaKIOcCyvM8ogQoDaZVks5qatxAgaJpZM4C5Mwh
.

@deepfriedbrain I too wish I knew and considered that when I used this library.

I'm almost finished writing all the basic functionality. But I have two 409 row tables containing 1632 radio buttons each.

@dantman In the next version I'm looking into creating a material data grid with virtualized scrolling (in addition to a regular table, which will also be more performant than the current with checkboxes etc)

I'm using react, redux and material-ui (v0.15.4) with Cordova. Grid and List performance on iOS is really a killer for the framework. Even scrolling seems to be a big issue, while quite acceptable on Android it is horrible on iOS.

Focusing on performance improvement should be really a high priority.

@bardu

This is in progress

Looking forward to any improvements in this area. We have a fairly simple form, but just tabbing through it entering values is very noticeably sluggish. Example: enter "200" in one textbox, press tab, enter "300" in the next one: tab takes half a second (!), so the first couple of digits of "300" are swallowed.

@nathanmarks is there any way to see an ETA or timeline for version 16? (would be nice to know if we're talking about weeks/months/years)

Kind regards and thanks for the hard work!

@jeroencoumans 0.16.0 is going to be a regular release for some other breaking changes very soon. next will come in a couple of months.

Simulator IOS animations look fine in my app. Very responsive on text box tabbing. Not sure if the simulator is throttling a slower CPU though to a true iphone 4s for the slowest experience. I sold my iphone 4s which is very slow on most web pages in safari.

Clicking buttons is also extremely fast with the highlight animation onclick of a raised button.

Sorry to barge in like that, but do you plan to replace the inline styles with CSS in the next version? I could not find a road map for the version labeled next..

@kenjiru You can read about it here
Next version seems to be using JSS

I'm closing. I think that the #5868 as well has the new styling approach of the next branch is addressing the overall issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

newoga picture newoga  Â·  3Comments

reflog picture reflog  Â·  3Comments

zabojad picture zabojad  Â·  3Comments

ryanflorence picture ryanflorence  Â·  3Comments

sys13 picture sys13  Â·  3Comments