ionic-framework: [v4 beta-13]: perf: Rendering / performance regression compared to v3 rendering
Bug Report
Ionic Info
Ionic:
ionic (Ionic CLI) : 4.2.1
Ionic Framework : @ionic/angular 4.0.0-beta.13
@angular-devkit/build-angular : 0.7.5
@angular-devkit/schematics : 0.7.5
@angular/cli : 6.1.5
@ionic/angular-toolkit : 1.0.0
System:
NodeJS : v10.11.0 (/usr/bin/node)
npm : 6.4.1
OS : Linux
Describe the Bug
Ionic v4 seems to suffer from huge performance degradation and visual artifacts when re-rendering template compared to V3.
The issue is visible even on very small form with segment button conditionally rendering a form with ion-list with just 6 elements.
Ionic V3: The whole screen changes at once, providing good user experience.
Ionic V4: The rendering is slower, doesn’t happen at once, instead visual artifacts are rendered (first elements are not rendered at all, then some of them are rendered without CSS styles, then CSS is applied).
Those artifacts are very annoying in our production app where the issue is much worse than here and it was noticed by all beta users / developers. We had to stop our migration process before this issue is resolved.
They’re mostly okay on fast mobiles, but for example on iPhone 5S the repainting / reflowing is clearly visible.
Steps to Reproduce Steps to reproduce the behavior:
- Open the sample app (or any Ionic app that uses *ngIf to conditionally render Ionic components)
- Switch to Chrome Dev Tools / Performance, enable CPU 6x slowdown and run profiling, enable screenshots
- Click on the segment buttons, stop profiling
- Check the screenshots in Chrome
- Ionic v3 renders fine (switches from state A to state B), v4 has visible visual artifacts
Related Code https://github.com/gitdude1458/ionic-v4-rendering-slow
Video: V3: https://raw.githubusercontent.com/gitdude1458/ionic-v4-rendering-slow/master/v3.webm
Video: V4: https://raw.githubusercontent.com/gitdude1458/ionic-v4-rendering-slow/master/v4.webm
It’s better to use Chrome screenshots to see the artifacts, video has low FPS.
Expected Behavior Ionic V4 should render at least as well as V3.
Additional Context Problems are much more visible in our production app, esp. on iPhone 5S and slower Android phones.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 12
- Comments: 17 (5 by maintainers)
I think what’s happening here is they async rendering of the component. Since the components render async, you’re getting the “waterflow” effect as they each render and become hydrated. It’s not technically a performance issue, though it is pretty jarring. Looking into a fix
@gitdude1458 I had the same conclusions as you: https://github.com/ionic-team/stencil/issues/1107 There you’ll find screenshots of the rendering performance, captured by Chrome DevTools, and StackBlitz demos that exhibit that rendering a 200 items list takes 100ms on Ionic 3 compared to 1500ms on Ionic 4!
@mhartington, as said by @gitdude1458, the problem comes from forcing rendering to happen during
requestAnimationFrame
:requestAnimationFrame
windows of 16ms. As a result, the browser is having lots and lots of relayouting phases which kills the rendering performance.When I did force the flush of the queue in one shot, by removing that “less than timeout” here in Stencil, then it had almost (still 2 times slower) the same performance as Ionic v3.
While working DOM only during
requestAnimationFrame
makes sense when you are doing few changes while having animations, it does not when you have lots of changes at a time. I think it is a very big drawback of the way Stencil currently works.I really expect that you guys provide a way to toggle this behavior before the final release. In its current state performance-wise, it would be unprofessional of me to deliver an application based on Ionic 4.
Anyway, that is not very reassuring even if it is a beta!
We are well aware of this issues and we have already made further changes in ionic beta.15 to improve the situation.
We also have an on going research to reduce drastically the cost of initialisation of web components with stencil, check out some WIP here: https://github.com/ionic-team/stencil/pull/1192
Looks like my suspicion was right. I tried following things:
Increase the timeout in queue-client.ts - helped - you could still see some visual artifacts - but at least not partially styled / updated components - the text would still scroll though
Disable use of requestAnimationFrame in Ionic - this actually helped a lot, now the whole UI was rendered at once (while lowering FPS, but that is not the issue).
Ionic V4 is still slower than V3 when it comes to rendering, but at least those visual artifacts / visible partial renderings are gone. By no means I believe disable requestAnimationFrame is proper solution at all, it’s ugly hack. I think Ionic team needs to implement some sensible frame batching to properly update the content of screen. It seems to work fairly well for page switching, but very poorly when individual template changes (which I believe is totally legitimate thing to do and a must for lot of apps) and/or is complex.
But anyway in case anybody is facing similar issue, it is possible to workaround the rendering artifacts by completely disabling requestAnimationFrame by placing this code in your app init:
It’s dirty, ugly hack, it doesn’t make the rendering faster (it’s still slower than V3), but at least it doesn’t show partially rendered layout, which was huge issue on slower phones in our app