evancohen / smart-mirror

The fairest of them all. A DIY voice controlled smart mirror with IoT integration.
http://smart-mirror.io
2.8k stars 693 forks source link

Performance Optimizations #345

Open evancohen opened 8 years ago

evancohen commented 8 years ago

It's been a while since I've looked at the mirror's performance. The start-up time is getting pretty bad, and I feel like it no longer feels smooth. I'm going to spend some time investigating the following:

https://github.com/evancohen/smart-mirror/commit/175dc9850d447aedaa824dca96ebcb82aec1569b I made a few optimizations to the way that FitBit loads in its dependencies, for most users this should decrease start time by 25% and use way less memory.

  • [X] Minimize/Avoid Watchers. Angular uses dirty checking to keep track of all the changes in app, we've been pretty careless about creating these and I think it's creating a performance impact.
  • Stay away from {{}} type bindings.
  • Leverage $watchCollection for calendar and other lists.
  • Use ng-if instead of ng-show.

https://github.com/evancohen/smart-mirror/commit/b12bfb6eca2acd7ae309a7610c261ad5a26672bc used ng-if for a 7% performance increase on boot. https://github.com/evancohen/smart-mirror/commit/ac225cf36de5e64243472ef7fbd9f2f6fc63167a eliminated brace style binding for ng-bind. This improves performance over time and saves ~20% every scope.$digest

  • [x] Greedy Services. Today, most services initialize themselves when the mirror loads - for some service (ie: weather, calendar) that is necessary, but for others that load on command we should defer (ex: Dilbert, XKCD).
  • [ ] Use Angular Components. The code has gotten a bit tangled and we are loading in a bunch of things that really should be brought in "on demand".
  • [ ] Memory leaks. Some people (like @7h30n3 below) have reported that the mirror crashes or becomes unresponsive after running for long periods of time. This could be due to a memory leak, I'll need to start running tests for this on a more regular basis.
  • [ ] Don't Use Angular 1.x. Some options:
  • Move to Angular 2. Along with a bunch of performance optimizations, Angular 2 also users TypeScript, which would be hugely beneficial to our build system endeavors and improving the quality of PRs.
  • Use React. A port to React.JS would be a lot of work, but would give us some great benefits (It's nice to the DOM and is known for it's performance).

Notes: I don't want to focus too much on boot time, in most cases the mirror boots and then is left running for a long period of time. The bulk of the optimizations that I would like to make here are for lower CPU usage over time and quick responses to commands.

Aforementioned Chart: Generated on a beefy Windows machine using Chromium Profiler in the Dev tools. image

kurtdb commented 8 years ago

I created the performance-improvements branch to see what we can do to make it stable.

A few pieces of advice I got from a colleague:

Might also be a good idea to look into directives to keep the HTML clean. It is usually only used for reusable components, but in a one-page layout project like this it might also have its use.

7h30n3 commented 8 years ago

Performance improvements would be very appreciated.

After I finally finished the frame for my smart-mirror I made a long-term test (over night). As I wanted to talk to the mirror in the next morning it was totally unresponsive. For example it detects the hotword, but before the white shine at the button appears the mirror already stops listening.

Also I have a constant cpu load of 40% (Pi2). I think thats because of the hotword detection.

evancohen commented 8 years ago

@7h30n3 believe it or not, the hotword detection/keyword spotting is just about the most efficient thing in the mirror today 😉, for the Pi Zero it uses < 10%. I don't think 40% CPU load on the Pi 2 is all that bad, to be honest. We might be able to optimize some things here, but the optimizations that we can make for the mirror likely won't decrease overall CPU consumption by much, mostly because x just isn't that optimizable for what we are doing.

Regarding the mirror being unresponsive: uh oh! that's exactly what we don't want happening. This could be because of a memory leak (I've added a task here to investigate it).