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 aListTile
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 theListView
?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 thejava.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.