Skip to content

Commit

Permalink
Performance improvements (#352)
Browse files Browse the repository at this point in the history
* only add fitbit dependencies if the user has fitbit in their config

* using ng-if for binding intensive elements. 7% perf improvement 😄

* improve performance of digest binding

* only add fitbit dependencies if the user has fitbit in their config

* rebasing calendar fixes onto performance

* using ng-bind for calendar

* replacing missing closing parenthasese

* replacing missing closing parenthasese and bonus char

* lastfm config object should be optional
  • Loading branch information
evancohen authored Jul 22, 2016
1 parent 83dd214 commit 7f451de
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 83 deletions.
71 changes: 33 additions & 38 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,20 @@
<body ng-controller="MirrorCtrl" ng-cloak="">
<div class="top">
<div class="top-left">
<div class="date grey">{{date.format('dddd')}}, {{date.format('LL')}}</div>
<div class="time">{{date.format('LT')}}</div>
<div class="date grey"><span ng-bind="date.format('dddd')"></span>, <span ng-bind="date.format('LL')"></span></div>
<div class="time" ng-bind="date.format('LT')"></div>
<ul class="calendar fade" ng-show="focus == 'default'" ng-class="config.calendar.showCalendarNames ? 'show-calendar-names' : ''">
<li class="event" ng-repeat="event in calendar" ng-class="(calendar[$index - 1].label != event.label) ? 'day-marker' : ''">
<div class="event-details">
<span class="day">
<span>{{event.startName}}</span>
<span ng-if="event.startName != event.endName"> - {{event.endName}}</span>
<span ng-bind="event.startName"></span>
<span ng-if="event.startName != event.endName"> - <span ng-bind="event.endName"></span></span>
</span>
<div class="details calendar-name">{{event.calendarName}}</div>
<span class="summary">{{event.SUMMARY}}</span>
<div class="details calendar-name" ng-bind="event.calendarName"></div>
<span class="summary" ng-bind="event.SUMMARY"></span>
<div class="details" ng-if="event.start.format('LT') != event.end.format('LT')">
<span ng-if="event.startName != event.endName">{{event.start.format('M/D')}} {{event.start.format('LT')}} - {{event.end.format('M/D')}} {{event.end.format('LT')}}</span>
<span ng-if="event.startName == event.endName">{{event.start.format('LT')}} - {{event.end.format('LT')}}</span>
<span ng-if="event.startName != event.endName"><span ng-bind="event.start.format('M/D')"></span> <span ng-bind="event.start.format('LT')"></span> - <span ng-bind="event.end.format('M/D')"></span> <span ng-bind="event.end.format('LT')"></span></span>
<span ng-if="event.startName == event.endName"><span ng-bind="event.start.format('LT')"></span> - <span ng-bind="event.end.format('LT')"></span></span>
</div>
<div class="details" ng-if="event.start.format('LT') == event.end.format('LT')">All day</div>
</div>
Expand All @@ -81,20 +81,20 @@
<div class="weather-today">
<span class="icon dimmed wi {{currentForecast.wi}}"></span>
<canvas id="icon_weather_current" width="90" height="70"></canvas>
<span class="temperature" ng-show="currentForecast.temperature">{{currentForecast.temperature}}&deg;</span>
<span class="temperature" ng-show="currentForecast.temperature" ng-bind="currentForecast.temperature + '&deg;'"></span>
</div>
<div class="weather-week-descriptor">
<span>{{minutelyForecast.summary}}</span>
<span>{{hourlyForecast.summary}}</span>
<span>{{weeklyForecast.summary}}</span>
<span ng-bind="minutelyForecast.summary"></span>
<span ng-bind="hourlyForecast.summary"></span>
<span ng-bind="weeklyForecast.summary"></span>
</div>
<div class="weather-week" ng-repeat="forecast in weeklyForecast.data" ng-if="$index > 0">
<div class="weather-week-day">
<span class="day light-grey">{{forecast.day}}</span>
<span class="day light-grey" ng-bind="forecast.day"></span>
<canvas id="icon_weather_{{forecast.counter}}" width="33" height="25"></canvas>
<span class="icon-small dimmed wi wi-fw {{forecast.wi}}"></span>
<span class="temperature temperature-min">{{forecast.temperatureMin}}&deg;</span>
<span class="temperature temperature-max">{{forecast.temperatureMax}}&deg;</span>
<span class="temperature temperature-min" ng-bind="forecast.temperatureMin + '&deg;'"></span>
<span class="temperature temperature-max" ng-bind="forecast.temperatureMax + '&deg;'"></span>
</div>
</div>
<!-- Workaround: -->
Expand All @@ -104,21 +104,21 @@
</div>
<div class="traffic" ng-repeat="traffic in trips">
<div ng-show="!traffic.error" class="traffic-information">
<span class="time-to">{{ 'traffic.time_to' | translate:traffic }}</span>
<span>{{traffic.duration.humanize()}}</span>
<span class="time-to" ng-bind="'traffic.time_to' | translate:traffic"></span>
<span ng-bind="traffic.duration.humanize()"></span>
</div>
</div>
<div class="stock">
<div class="stock-information" ng-repeat="quote in stock">
<span><i class="fa fa-rss fade" style="margin-right: 5px";></i></span>
<span fade>{{quote.Name}}: ${{quote.LastTradePriceOnly | number : 3}} ({{quote.Change}}%)</span>
<span fade ng-bind="quote.Name"></span>: $<span fade ng-bind="quote.LastTradePriceOnly | number : 3"></span><span ng-bind="quote.Change"></span>
</div>
</div>
</div>
</div>
<div class="container" ng-class="(listening == true)?'listening':'not-listening'">
<div class="middle-center">
<h1>{{greeting}}</h1>
<h1 ng-bind="greeting"></h1>
<div class="contents-box video-container animate-grow" ng-show="focus == 'video'">
<iframe class="video animate-grow" ng-src="{{video}}"/></iframe>
</div>
Expand All @@ -127,7 +127,7 @@ <h1>{{greeting}}</h1>
<div><canvas id="visualizer" width="300" height="150"></canvas></div>
<img class="sc" ng-src="{{scThumb}}"/>
<img class="scWaveform" ng-src="{{scWaveform}}"/>
<h2 class="sc">{{scTrack}}</h2>
<h2 class="sc" ng-bind="scTrack"></h2>
</div>
<div class="contents-box map animate-grow" ng-show="focus == 'map'">
<img class="contents map animate-grow" ng-src="{{map}}"/>
Expand All @@ -140,48 +140,43 @@ <h2 class="sc">{{scTrack}}</h2>
</div>
<div class="dilbert-container animate-grow" ng-show="focus == 'dilbert'">
<img class="dilbert animate-grow" ng-src="{{dilbert.content}}"/>
<div class="comic-title">{{dilbert.title}}</div>
<div class="comic-title" ng-bind="dilbert.title"></div>
</div>
<div class="reminders-container animate-grow" ng-show="focus == 'reminders'">
<ul>
<li class="reminders animate-grow" ng-repeat="reminder in reminders">
<span class="reminder">{{reminder}}</span>
<span class="reminder" ng-show="reminder"></span>
</li>
</ul>
</div>
<div class="contents-box animate-grow" ng-show="focus == 'timer'">
<div class="contents-box animate-grow" ng-if="focus == 'timer'">
<div class="contents timer animate-grow">
<div class="timer-countdown">{{timer.countdown | secondsToDateTime | date:"mm:ss"}}</div>
<div class="timer-duration grey">{{timer.duration | secondsToDateTime | date:"mm:ss"}}</div>
<div class="timer-countdown" ng-bind="timer.countdown | secondsToDateTime | date:'mm:ss'"></div>
<div class="timer-duration grey" ng-bind="timer.duration | secondsToDateTime | date:'mm:ss''"></div>
<timer-circle class="timer-circle" />
</div>
</div>
</div>
<div class="bottom-center">
<!-- Command list -->
<div class="commands animate-grow" ng-show="focus == 'commands'">
<h2>{{ 'commands.title' | translate }}</h2>
<div class="commands animate-grow" ng-if="focus == 'commands'">
<h2 ng-bind="'commands.title' | translate"></h2>
<dl>
<dt ng-repeat-start="command in commands">{{command['text']}}</dt>
<dd ng-repeat-end>{{command['description']}}</dd>
<dt ng-repeat-start="command in commands" ng-bind="command['text']"></dt>
<dd ng-repeat-end ng-bind="command['description']"></dd>
<dt ng-show="fitbitEnabled">Show my walking</dt>
<dd ng-show="fitbitEnabled">Refreshes fitbit data.</dd>
</dl>
<small>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</small>
</div>

<div class="news">
<div class="fade" ng-show="focus == 'default' && news">
<div class="fade" ng-if="focus == 'default' && news">
<div class="news-title dimmed fade">
<span><i class="fa fa-rss fade" style="margin-right: 5px";></i></span>
<span fade>Source: {{news.title}}, Last Updated: {{news.lastUpdated.format('MMM DD, h:mm a')}} </span>
<span fade>Source: <span ng-bind="news.title"></span>, Last Updated: <span ng-bind="news.lastUpdated.format('MMM DD, h:mm a')"></span></span>
</div>
<div class="news-content fade">
<span class="fade">{{news.content}}</span>
<span class="fade" ng-bind="news.content"></span>
</div>
</div>
</div>
Expand All @@ -190,7 +185,7 @@ <h2>{{ 'commands.title' | translate }}</h2>
<div class="interim-result" ng-bind="interimResult" ng-hide="speechError"></div>
</div>
<div class="bottom-left">
<div class="fitbit" ng-show="fitbitEnabled">
<div class="fitbit" ng-if="fitbitEnabled">
<div><span class="fitbit-title">{{'fitbit.statsFor' | translate}} {{fbDailyAverage.fullName}}</span></div>
<div><span class="fitbit-item">{{'fitbit.averageSteps' | translate}}: {{fbDailyAverage.averageDailySteps}}</span></div>
<div><span class="fitbit-item">{{'fitbit.todaysSteps' | translate}}: {{fbToday.summary.steps}}</span></div>
Expand Down
2 changes: 1 addition & 1 deletion js/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@
});
}

if(typeof config.lastfm.key !== 'undefined' && config.lastfm.user !== 'undefined'){
if(typeof config.lastfm !== 'undefined' && typeof config.lastfm.key !== 'undefined' && config.lastfm.user !== 'undefined'){
registerRefreshInterval(getScrobblingTrack, config.lastfm.refreshInterval || 0.6)
}

Expand Down
86 changes: 43 additions & 43 deletions js/services/fitbit.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
(function() {
'use strict';

var express = require('express');
var app = express();
var fs = require( 'fs' );
var Fitbit = require( 'fitbit-oauth2' );

function FitbitService($http) {

Expand Down Expand Up @@ -56,53 +51,58 @@
var fitbit = {};
if (typeof config.fitbit != 'undefined') {
fitbit = new Fitbit(config.fitbit);
}

// In a browser, http://localhost:4000/fitbit to authorize a user for the first time.
//
app.get('/fitbit', function (req, res) {
res.redirect(fitbit.authorizeURL());
});
var express = require('express');
var app = express();
var fs = require( 'fs' );
var Fitbit = require( 'fitbit-oauth2' );

// Callback service parsing the authorization token and asking for the access token. This
// endpoint is refered to in config.fitbit.authorization_uri.redirect_uri. See example
// config below.
//
app.get('/fitbit_auth_callback', function (req, res, next) {
var code = req.query.code;
fitbit.fetchToken( code, function(err, token) {
if (err) return next(err);
// In a browser, http://localhost:4000/fitbit to authorize a user for the first time.
//
app.get('/fitbit', function (req, res) {
res.redirect(fitbit.authorizeURL());
});

// persist the token
persist.write(tfile, token, function(err) {
// Callback service parsing the authorization token and asking for the access token. This
// endpoint is refered to in config.fitbit.authorization_uri.redirect_uri. See example
// config below.
//
app.get('/fitbit_auth_callback', function (req, res, next) {
var code = req.query.code;
fitbit.fetchToken( code, function(err, token) {
if (err) return next(err);
res.redirect('/fb-profile');
});
});
});

// Call an API. fitbit.request() mimics nodejs request() library, automatically
// adding the required oauth2 headers. The callback is a bit different, called
// with ( err, body, token ). If token is non-null, this means a refresh has happened
// and you should persist the new token.
//
app.get( '/fb-profile', function(req, res, next) {
fitbit.request({
uri: "https://api.fitbit.com/1/user/-/profile.json",
method: 'GET',
}, function(err, body, token) {
if (err) return next(err);
var profile = JSON.parse(body);
// if token is not null, a refesh has happened and we need to persist the new token
if (token)
// persist the token
persist.write(tfile, token, function(err) {
if (err) return next(err);
res.send('<pre>' + JSON.stringify(profile, null, 2) + '</pre>');
res.redirect('/fb-profile');
});
else
res.send('<pre>' + JSON.stringify(profile, null, 2) + '</pre>');
});
});

// Call an API. fitbit.request() mimics nodejs request() library, automatically
// adding the required oauth2 headers. The callback is a bit different, called
// with ( err, body, token ). If token is non-null, this means a refresh has happened
// and you should persist the new token.
//
app.get( '/fb-profile', function(req, res, next) {
fitbit.request({
uri: "https://api.fitbit.com/1/user/-/profile.json",
method: 'GET',
}, function(err, body, token) {
if (err) return next(err);
var profile = JSON.parse(body);
// if token is not null, a refesh has happened and we need to persist the new token
if (token)
persist.write(tfile, token, function(err) {
if (err) return next(err);
res.send('<pre>' + JSON.stringify(profile, null, 2) + '</pre>');
});
else
res.send('<pre>' + JSON.stringify(profile, null, 2) + '</pre>');
});
});
});
}

// Only start up express and enable the fitbit service to start making API calls if the fitbit config is present in config.js.
if (typeof config.fitbit != 'undefined') {
Expand Down
5 changes: 4 additions & 1 deletion main.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const BrowserWindow = electron.BrowserWindow
const powerSaveBlocker = electron.powerSaveBlocker
powerSaveBlocker.start('prevent-display-sleep')

// Launching the mirror in dev mode
const DevelopmentMode = process.argv[2] == "dev";

// Load the smart mirror config
var config;
try{
Expand Down Expand Up @@ -59,7 +62,7 @@ function createWindow () {
mainWindow.loadURL('file://' + __dirname + '/index.html')

// Open the DevTools if run with "npm start dev"
if(process.argv[2] == "dev"){
if(DevelopmentMode){
mainWindow.webContents.openDevTools();
}

Expand Down

0 comments on commit 7f451de

Please sign in to comment.