[HABpanel] Increased CPU usage demo

Tags: #<Tag:0x00007f433d48f2b0> #<Tag:0x00007f433d48f1e8>

Hello,

First of all I must say this UI is awesome. It is so easy to customize it.
But on my old Nexus 7 tablet I saw high cpu usage. So I researched a bit.

I submitted my first result to github. I was able to reduce the $digest cycles massive to now 1-3. Maybe this is a start for some optimizations, but at the moment this is only a draft.

See last two commits

2 Likes

Very interesting, I’ll try it out soon! Thanks!

I disabled the clock for this demo because it causes a full refresh every second.
My openHAB environment has many items with regular updates. This will run the openHAB service very often (about 500-1000ms).

I think it can be a problem with the “template widget”, if the user does not store the items in the settings. In this case we do not know which items are used.
But we could add a checkbox in the settings to that allows the widget to get all change events.

When an item is updated, its name is sent with the 'openhab-update' event as a parameter.
Since most widgets subscribe to updates for a particular item using OHService.onUpdate, this function should definitely be changed so it only calls the callback function if the item being updated matches (if no item is provided, then it should call it no matter what).
The template widget is different since it accesses $rootScope.items directly - but it could indeed watch for any update and recompile the template manually every time.

I have now added a optimized "Template Widget"version to my fork. If the custom widget uses items in the settings the widget only listen for these items.

So, now most of the widgets are optimized on my fork.

1 Like

is there any plan to create a pull request to merge it back?

I’m currently in the same situation. I have a openhab system with ~600 items, but only ~10-20 of them are updatet every minute.

My Tablet is running with constant 30% CPU. A further side effect is that there is a noticeable delay between user interactions and my guess is that is related to each other.

I think @ysc should say if this kind of modification has a change for a pull request. Maybe the direction is wrong, I’m not an Angular expert. I’ve checked the changes and they are still compatible with the lastest version.

I think they are not really compatible, because they change the default behavior.

But it is a good starting point and a huge improvement. We should think about how we can use this improvement in a compatible way.

At this point I think everything causing potential breakages has to be properly tested for regressions before it can be merged - the vast majority of users is fine the way it is, and not ensuring reliable updates to fix performance would be imho worse.

That being said, your approach makes sense @csowada, I’m not against altering the digest cycle and calling $digest directly in widgets, but I believe it should be behind some global switch like “enable partial updates (experimental)” that only affected users would have to turn on. Otherwise I feel better simply calling $apply when an update occurs so we’re sure everything is updated.

@holger_hees 10-20 updates a minute is not that much, but probably you have a lot of complex template widgets. Maybe there’s an obvious bottleneck that is causing the majority of your problems - profiling with Chrome’s performance tool (tutorial: https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/) could isolate it. I let it run as a test and apparently the slider is the main bottleneck in my particular case, maybe you would find something too:

currently I try a different approach which don’t needs a patch.

Instead a created my own directive, which I use to wrap all my custom widgets inside.

  1. This directive is catching and preventing all angular digest cycles.
  2. It automatically detects all used items during the first full digest cycle which is not blocked
  3. It is listening for item updates and it resumes the angular digest cycle only if a item was updatet which is used inside this widget.

This is reducing my CPU usage from 15-20% to 2-3%

if anyone is interested, I can share my code.

I released my latest code as part of this thread now.