cancel
Showing results for 
Search instead for 
Did you mean: 

Improving scrolling performance with sap.m.App and sap.m.Page

Former Member
0 Kudos

Hi,

I'm working with a side project called openui5-cards and are experiencing some issues with scrolling performance. As far as I can see, the problems are general for sap.m.App and/or sap.m.Page and not specific for my components (therefore it should also affect all other sapui5 apps such as fiori)

I'm testing this on desktop chrome and android 4.4 chrome/webview, but I assume these issues are for all browser.

The goal is to have a 60 fps experience when scrolling which leave 16 ms pr frame to be rendered.

When the user is scrolling, it's essential that the whole screen is not repainted after a scroll event. If this happens, you will not be able to reach the 60 fps goal.

I've solved the issues when adding my custom components directly to a div, but am still experiencing issues when adding it to a sap.m.Page and sap.m.App. To reproduce the problems, I've three examples:

http://elsewhat.github.io/openui5-cards/cdn/0.1/example3-1perfissue.html

Here the open.m.CardContainer is added directly to the div (no sap.m.Page or sap.m.App).

This example suffers from full repaint when scrolling

http://elsewhat.github.io/openui5-cards/cdn/0.1/example3-2perfissue.html

Same as the above, but have added the following style:

body{

  background-attachment:scroll;

}

The property background-attachment was set to value fixed by sapui5, but here we've overwritten it.

This example does not suffer from full repaint, and is working as we want

http://elsewhat.github.io/openui5-cards/cdn/0.1/example3-3perfissue.html

Same as above, but are adding the open.m.CardContainer to a sap.m.Page which is then added to a sap.m.App that is bound to the content div.

This example suffers from the full repaint when scrolling

(and is the one we want to solve)

To help you understand the video, I've created a short screenrecording showing the repaint issue more clearly. It uses the chrome dev tools timeline.

Improving performance with openui5 and sap.m.App and sap.m.Page - YouTube

Any ideas where to fix this issue ?

Accepted Solutions (1)

Accepted Solutions (1)

AndreasKunz
Advisor
Advisor
0 Kudos

Hi Dagfinn,

yeah, this is better than the 140-characters-restricted Twitter attempt... so I can explain better what's happening. 🙂

There are TWO backgrounds:

  • one is the background attached to the <body>. You see this one in the first two examples; in the second you modified to repaint much faster when scrolling (but this also changed the visual appearance, I'll come to this later).
  • a sap.m.App control (and SplitApp and Shell) uses the full window size and brings its own background (which is on top of the one described above).So as soon as you use an App control (and you probably did so when wrapping the cards into a Page control), you are seeing a different background (which just looks identical). Your change to the background "in the background" doesn't have any effect now.

What was the original issue? When the background (the white stripes on blue gradient) are fixed, but the content is scrolled, in the browser's graphics realm there are two layers which are moved on top of each other, the upper layer being transparent in places (where there are no cards). Whenever the upper layer moves, different parts of the background gradient may become visible, so the browser has to redraw everything.

When the background moves together with the foreground, both merge into one graphics layer, which can be just moved around (this is quite cheap, even the old Atari STE had a special chip to make this kind of operation very fast). The browser only has to paint the tiny bits that are scrolled into view.

So this is the improvement you did between example one and two.

(I'm sure you know it, I just wanted to write it explicitly.)

Now in example 3 we are not looking at the same background. We are looking at a new background which looks the same, but is technically the background of one <div> that belongs to the App control and takes exactly 100% by 100% of the screen (the element with ID "__app0-BG"). This div does not scroll, so there is no need for "background-attachment: fixed in the CSS". The whole element is just statically sitting there.

But there is the Page control which now offers scrolling inside a certain sub-area of the screen (the <section> mentioned by Jason is the frame and its child element is the larger area which holds the content and is scrolled).

So from the perspective of the browser's graphics engine we have the same situation as in the first example: one layer which has the background pattern, and one layer with content moving over this background. Again two layers which need to be re-combined for every scroll step.

The easiest way to do your performance improvement on this level would be to apply the same background on the scrolled area - the element with ID "openui5-cards-scroll". This would make the background scroll together with the content, so the browser only has to paint the new areas during scrolling and can just move the rest.

However, the change you did also affected the visual appearance:

  1. The background stretches to the height of the page content. So the gradient changes brightness rapidly on short pages and cannot be even recognized as gradient when looking at very long pages without scrolling: you only see the bright uppermost part, or the dark bottom part, or something in between. You only see a fraction of the gradient at a time. Navigation between pages of different size may then also mean that you slide from a dark bottom part of one page to a bright top part of another page.
  2. The background moves when scrolling. It's obvious - this is exactly your change. But it makes a difference to the eye. It gives more of a technically "clever" impression when not everything moves the same speed. I'm not saying a fixed background looks better, but, well, it might indeed look more appealing to some. Remember how parallax scrolling is also often used as means to make something look "nicer".

Of course when scrolling performance is totally bad, then it's much better to accept these two visual changes in favor of better performance, but especially on Chrome I didn't really notice scrolling to feel slow.

We really have to explicitly test this on weaker mobile devices, though. So of course thanks a lot for the hint!!!

There's another reason for fixing the background, by the way:

When a different background image is used, e.g. some vacation photo, or just a shadow of a company logo (can be easily done in Theme Designer), then it is not an option to stretch it to the height of the page!

You'd also not like to scroll up and down your vacation photo all the time or to see the feet of your son on one page and then his head on the next or so.

So with a background image which is more than just a pattern, fixing the background and limiting its size to the screen size is a "must".

Regards

Andreas

AndreasKunz
Advisor
Advisor
0 Kudos

Ok, one detail to add: the background gradient is semi-transparent.

This means:

  1. even with the App covering the whole body, the browser has to draw and combine both, the <body> and the App background. This is only an initial issue, though, as both don't move with respect to each other.
  2. just adding the same body background to the scroll container div (as I proposed above) will not avoid the issue: the fixed background still shines through and needs to be painted. Instead, the gradient needs to be modified to colors with no alpha value.

However, testing in the Chrome developer tools shows that not even this, or even setting a solid background color avoids the complete repaint!

I removed all other background gradients then (body+App), then the repaint time decreased significantly (maybe a third of the 60 fps mark -> 180fps).

Then I added the gradient to the body again (note: this gradient is fully covered! it cannot be seen!) - and the performance dropped to close to the 60 fps mark again.

So it looks like even invisible gradients impact the redraw performance of Chrome.

That's new to me and certainly a surprise. And needs to be considered...

AndreasKunz
Advisor
Advisor
0 Kudos

I'm not so much concerned about Chrome performance - even though the numbers show a dramatic difference, I don't feel any scrolling slowness - it's still 60fps (or close to it), after all.

I'm more concerned about weaker (mobile) devices, e.g. about the first retina iPad which had a bad pixels/CPUGPUpower ratio.

But as always, actual devices behave different than one expects: it seems to completely ignore "background-attachment:fixed" (the one applied at the body). The background SCROLLS! That one is running iOS 6. The same for iPad mini and iPhone 5 with iOS7.

The background of the sap.m.App control is constructed in a way that it is fixed even without "background-attachment:fixed", so I tested this as well with the mentioned devices. And it felt perfectly fine, very fast.

On a Galaxy S2 with Android 4.1.2 it does not feel very smooth, but there the same is the case for regular we pages or even native apps. Making the background solid does not change the performance there.

So overall it does not seem like there is a notable impact for the user on actual devices.

And one has also to consider that scrolling inside Page controls is done by JavaScript, using the iScroll library, so this makes it automatically slower and any perceived slowness (e.g. on Android) is more likely to be caused by that fact.

When you look at the recording of the frame painting in the third example with sap.m.App, you'll notice that one the one hand the painting takes considerable time, and more than in your optimized version.

But on the other hand it only takes 8.x milliseconds for each frame and you see how the browser is idle half of the time because for the 60fps (which are apparently the targeted frame rate) the browser has 16.7 milliseconds for each frame.

So the browser could draw it faster (up to ~120fps) but does not see any need to do so. So I'm not sure how it would feel slow to a user...

Still, thanks again a lot for your great effort! The video is a fine guide for anyone who wants to track down performance issues. And the particular example could have turned out to be a really big issue.

Even if it is not really slower on Chrome, it certainly consumes more CPU cycles the way scrolling (and the theme) is implemented right now - and when thinking of mobile device battery life, this actually is a concern.

Regards

Andreas

Former Member
0 Kudos

Hi,

Again, thanks for the detailed response.

The main use case for the openui5-cards component is mobile and currently the scrolling performance is not good enough (at least not on android which I've focused on so far)

I've recorded a quick demo of the performance on a nexus5 (android 4.4) running the latest chrome beta.

As you can see from the fps counter, the performance is significantly below 60 fps and the experience suffers

Demonstration of scrolling performance with openui5-cards - YouTube

The full repaint is probably not the only issue causing the fps to drop below 60 fps, but I'm convinced it is a significant contributor (that we ought to be able to avoid)

Will try to create a comparison example that has the same content, but doesn't have the scrolling problems (and probably not the javascript scrolling library)

Former Member
0 Kudos

Looked a bit more into it today.

Managed to get away the full repaint by:

1.enableScrolling:false on the page

2. overwrite the following values

.sapMNav{

    overflow:visible;

}

.sapMPageScroll{

    overflow:visible;

}

Couple of examples with the fix

openui5-cards Google+

openui5-cards reddit

There is a night and day difference on performance for mobile

(but unfortunately, do not have the time to demonstrate this in a good way right now).

PS new problem now that the scrollbars do not appear on chrome beta for android (works with chrome for android). Strange

PSS found some good tips in DevTools: Visually Re-engineering CSS For Faster Paint Times

jmoors
Active Contributor
0 Kudos

Looks good, do you think the repaint improvement is because of the background image is not covering the full height of the page, and therefore not having to redraw??

Interesting blog will have a proper read tomorrow.

Thanks,

Jason

Answers (3)

Answers (3)

Former Member
0 Kudos

Hi,

I'm doing an app for mobile, and I'm facing a problem of scrolling from left to right. I can scroll up and down, but I can´t scroll left to right. As I can´t do the scroll I'm not able to see all the content of my page. Can anyone help me?

Thanks in advance,

Raissa Almeida

jmoors
Active Contributor
0 Kudos

Looks like the slowdown is because it's using overflow-x:auto property to implement the scrolling of the card content section.

<section id="openui5-cards-cont" style="overflow-x: auto; overflow-y: auto;">

Former Member
0 Kudos

Thanks,

As far as I can see, I need the overflow-y:auto in order to get any scrollbars at all.

Therefore I don't see it as an option to remove it.

jmoors
Active Contributor
0 Kudos

Interesting issue, on first glance I see the example 3-3 displays the page header which is full width, so it's scrolling an element rather than the whole page??

devtools has the option to show the repaint bottlenecks, just tried and it shows there is an issue for the 3-3 example.

Will have a better look later.

Jason