I have a custom ListCell implementation, shown in the picture below.
The left side, which represents the date, consisting of 3 labels, put in a VBox and the "CounterContent" consisting of the counter, with a TextField for each digit, contained in a HBox, and two Hboxes containing labels for kWh, kWh/day and so on. And that seem to be just too much, to be running performantly.
I've tried to load the data in a background task, showing a progress indicator, while the task is running, but unlike on desktop, on android the performance is very poor. Whenever I switch to the listview, the garbage collection kicks in, and blocks the ui thread, so that the progress indicator never shows up.
I've tried it on a Huawei Y-300, Android 4.1.1, javafxports 8.60.6 (because javafxports 8.60.7 causes a bug, that makes TextField unusable), and on a Samsung S5 mini, Android 5+. On the Samsung phone the performance in general is way better, just like expected, because of the Ahead-of-Time compilation I guess, but there is still the garbage collection issue. Furthermore after the listview has been populated with cells, the scrolling is not very smooth.
Is the listcell to complex or what else could be the matter for the poor performance?
UPDATE:
After running a lot of tests it seems the unsmooth scrolling is not caused by performance problems. At least on the S5 (javafxports 8.60.7).
I removed all css styling, and replaced the textfields by a single label (the counter node is already a custom control(forgot about that), which lays out the textfields in 2 Regions(not HBoxes) and the nodes of the ListCell are instantiated in the constructor). Furthermore I switched the ListView for a CharmListView and set android.monocle.input.touchRadius=1.
None of these steps resulted in considerable improvement.
Just to clarify: In contrast to the Huawei phone, the scrolling on the S5 and android 5+ is usable, but it's not very smooth, which makes for a unsatisfactory user experience.
On the Huawei (javafxports 8.60.6), changing the counter textfields for a label, gave a significant improvement, but not to the point where the scrolling became usable. Until I set this magical experimental switch: gluon.experimental.performance=true, which makes the listview scrolling lightning fast(after a little warmup delay), but still not really smooth.
There are many reasons why the performance of a complex scene is reduced, so this is just a list of possible ideas that might help improving it, in any order.
ListCell
For starters, the number of nodes in the cell is really high. Notice that every single scroll you make means the full rendering of the virtual flow that holds the visible cells. And for every cell, that means recreating its content all over again.
Without viewing your code I can't tell, but you should avoid creating new instances of every node in the cell all the time, by having just one single instance, and in the updateItem method only change the content of the nodes.
Have a look at this sample. The NoteCell class is a custom cell, where a ListTile is used.
Number of nodes
Have you tried using just a Label to replace the 8 textfields and 3 boxes?
Cache
If you use images downloaded from Internet, use Gluon Charm Down Cache to avoid the same image being downloaded over and over again.
Have a look at this sample. Without the cache, even on desktop the performance is really affected.
Also use the JavaFX built-in cache for any node, trying different cache strategies.
CSS
Complex CSS requires long CPU time. Try to simplify it. Even you can remove the whole CSS for a quick test. Then decide what you may or may not use.
The same goes for animations: Avoid animations, transitions or even CSS effects, if possible.
Custom Control
The counter complex node could probably be replaced by a custom control that optimizes the rendering.
CharmListView
Have you tried using the Gluon Charm CharmListView control instead of the ListView?
There's a new experimental flag that you can use to test a possible optimization that might improve performance while scrolling the list. Set gluon.experimental.performance=true on the java.custom.properties file, and give it a try.
JavaFXPorts version
You mentioned you are using 8.60.6 because of the TextField bug. In this case, are your TextField nodes editable? If not, I'd suggest replacing them with other nodes and running with 8.60.7, since it contains a lot of performance improvements.
Performance tools
Use performance tools like Monitor and use its profiling options so you can trace down any possible bottle neck.
CPU
Last but not least: your mobile device specs are always critical.
Trying to render a complex scene on a Cortex A5, given that "it is the smallest, lowest cost and lowest power ARMv7 application processor", or using a very old Android 4.1.1, can't perform as well as running it on a brand new device with higher specs.
As you also mentioned, running on a Cortex A7 performs "way better". Have a look at this comparison, and find the right architecture for the job.
Anyway, there's always room for improvement, and a lot of effort is put into it. Your feedback is always welcome.
Related
I have a lot of FlexLayout element in my template and it is so slow on iOS devices.
i replaced that with StackLayout and now it became little fast than before.
I'd like to know which Layout Container is fastest layout in Nativescript.
There is never one right solution for all various needs, which is why we always have options and that applies to layouts in {N} too.
Learn more about layouts interactively at nslayouts.com and choose the one that suits your use case.
If you show use what exactly you are trying to achieve, we may able to give you some suggestion. There are some general guidelines you may have to follow for better performance,
Avoid nested layouts
Use GridLayout when you need known number of partitions in your UI, the less the number of partitions are, the better the performance would be. Use FlexboxLayout otherwise.
If you just want to stack items in vertical or horizontal order, StackLayout may be a good option. Use FlexboxLayout only when you want to use flex box specific features, like when items has to be wrapped to next line, change order of items etc.,
Try to not use StackLayouts just for the shake of borders around, since you can add border to the component itself.
If you have really complicated heavy UI components, you may load it once the page has completed navigation, that may be faster.
Prefer ListView over Repeater / for loop as much as possible.
By following the above at least I can confirm, I don't hit performance issues in my apps where I have 100s of elements and 10s of partitions on screen. If you still face issues, try creating a Playground example where we can see the issue.
I noticed this same thing with FlexboxLayouts on IOS where I was doing animations with the layouts. It worked great on Android, but was very slow on IOS. I switched it to a GridLayout, and things worked a lot better.
I am developing an aframe project on my MacBook pro, late 2013. When running the project, the fan of my computer always spins fast, regardless which browser I use (firefox, safari, chrome) and the project size (also happens with a project just containing a simple a-box).
aframe-stats show me that my project (1028244 vertices, 342748 faces) still runs with 20 fps.
Is it somehow possible to limit the frame rate to 10fps in order to keep my computer quite? Or any other way to limit the flop-consumption of the aframe project? I already tried a native approach with sudo cputhrottle plugin-container 10 but that did not just throttle the aframe-renderer but the whole firefox browser. Can I pull the break somewhere in the JavaScript or the Browser settings?
It's difficult to say without your project code. Large data sets will simply crank out even a high spec macbook pro. I have found it helpful to pause any rendering whenever possible to quiet the users' machines.
I personally removed automated next animation frame rendering in favor of waiting for controls and objects to change.
For example:
this.controls.addEventListener( 'change', function(e){ addToRenderStack(); });
A simple function addtorenderstack puts in a new value in a list for a render, with the expectation that the render will occur at some point in the future and not right away. the list can also be used to log who requested the render in the call stack, and narrow down performance hogs.
addtorenderstack places a render request in a list. In the requestanimationframe loop, if the list has any length, a render is called on the scene. The stack is immediately cleared rather than processed one by one. If controls or animations continue to make render requests, the list will have a length again and request animationframe will process them in the same way with another render.
In this way, the code only renders when absolutely required. This saved me much grinding on framerate and the fans only come on during intensive operations and then shutdown when its complete, much like a typical 3d game experience.
Your mileage may vary depending on what's happening in your app. I work in engineering so often the view of the 3d world is stopped as an engineer examines or shows a model.
I am making digital instruments for a car. These instruments will be constantly updated by information through ajax. These instruments will be served from a server onboard the vehicle through WLAN (fast) to my iPhone 3G. Is imperative to the success of the project that the updating of the tachometer is smooth and very responsive. Otherwise, it will look retarded.
The first problem I encountered was when I made this demo where tachometer moves quickly back and forth between zero and a thousand RPM: http://www.kingoslo.com/instruments/ When viewed on my iPhone 3G, the arrow simply doesn't move back and forth smoothly enough.
This javascript works by changing the source of the arrow img-element (which is semi transparant {4 color png} floating on top the static picture of the scale {16 color png}, by the way).
I've been made aware of new image editing features in HTML5, and wondered if any of those, or any other methods will be more responsive. Also, I am getting an iPhone 4 for xmas, so that may be a bit faster, but I've got the feeling that it still will fall short for the current build, especially when I add the constant ajax updating that is required to keep the instruments change values as the driver drives along.
Thank you for your time. Any help is greatly appreciated.
Kind regards,
Marius
I think using canvas will result in much faster animation - it was created to handle drawing, whilst manipulating DOM elements is comparably expensive.
Mobile Safari is compatible with canvas.
Alternatively, you could try incorporating all the angles as one large CSS sprite, and then just manipulating its background-position CSS property (element.style.backgroundPosition in the JavaScript DOM API).
I'm developing my first Android game and I'm having a bit of difficulty making the UI as smooth as I would like. I've spent a couple of hours googling around with no luck, I'm probably just searching for the wrong thing.
I have two different XML layout resources where each layout contains just one SurfaceView subclass. When I call activity.setContentView(R.layout.second_layout) to transition from the first layout to the second layout there is a noticeable period of time where a black screen (with a small white bar along the top) is displayed in between the two views.
I've tried various things such as; constructing the second view manually at runtime (i.e not using a layout XML file), calling activity.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out) after activity.setContentView(R.layout.second_layout) and attempting to render to the canvas before the view has loaded (turns out the canvas is unavailable).
I don't see other games (or apps) having this issue so I presume there is a reasonably simple solution.
If you need some more information about my particular situation in order to help out then please let me know what information is missing. Any help would be largely appreciated.
Update: My answer below was written in 2010. Since then Fragments have become the norm, particularly since Fragment nesting was made possible and the support library allows this functionality to be used in a backwards compatible fashion. As such, instead of transitioning to a new Activity to perform a new "user task", you can use the one Activity and push and pop fragments within that Activity's view hierarchy. Animations can also be performed as a part of a fragment transaction (e.g. Fragment transaction animation: slide in and slide out).
This became pretty apparent not long after posting this question, however I thought I should come back here and make it clear to everyone else.
Activities are positively the way to go when developing for Android. Don't be put off by the fact that a transition may seem too minor for a separate Activity, the very foundation of Android is built around the idea of an Activity.
I'm writing a video annotation application with Qt4 in which users need to be able to seek to various points in a video, putting markers on various objects and then setting keypoints for those markers so that they stay on the objects in the video as they move around. QGraphicsItemAnimation seems like a great place to start for these markers, however they need to be able to appear and disappear at specific times, which I can't figure out how to do with the QGraphicsItemAnimation. I could set the scale at 0 to make the objects disappear, but that seems like a pretty hacky solution, and I'm guessing that the paint engine would still waste cpu cycles trying to draw those invisible objects. Does anyone have a better solution than this? I'm using Qt 4.5.3 right now, but I'm willing to upgrade to 4.6 if it makes things easier. Thanks!!
It seems like the functionality you want of showing/hiding QGraphicsItem objects is beyond the scope of the simple "tweening" that the animation class performs. It is only for one object at a time, and any appearance or disappearance you have to write yourself.
You still might get some mileage out of QGraphicsItemAnimation (although the fact that it uses its own timer instead of being locked to the frame clock of your video is a little dodgy).
Neglecting "seeking" for a moment, there is a QTimeLine::finished() signal. If you let the end of an annotation's active animation timeline represent the point where you want it to disappear, you can trigger QGraphicsItem::hide() at that point. When it comes time to turn it back on, you would construct a new QGraphicsItemAnimation (based on the next run of keyframe data for that object) and call QGraphicsItem::show().
Note that one of the headlining features of Qt 4.6 is the QtAnimation framework, which is more sophisticated but also rather complex. I've not used it yet, but looking over the examples it seems like you might be able to "animate" a visibility or opacity property.