Tivity Presentation
Tivity Presentation
in
location.aggregator.mobile.webapp
INTRODUCTION
INTRODUCTION
a short introduction to
tivity
INTRODUCTION
In short you can access pretty much every page from every location through the footer menu.
homepage
favorites
exclude
listing
different
categories
search
listing
about
settings
detail page
gmaps route
[future]
STRUCTURE
Fair warning, some of the features described in the pages below arent even
implemented yet, the application is still a
work in progress, this document is only a
presentation of whats to come.
DESCRIPTION
detailed description of
the application
Im trying to make the project presentation as good as possible for the sake of posterity, even if I
actually dont have a lot of detailed information, because it is not so relevant in the scope of this DEMO
application.
The juicy parts are in the way the application is built, the technologies used, and so on and so forth,
therefore I will concentrate most of my focus to add quality content in that part of the project specs.
The homepage will be mainly for loading reasons only, giving the user a sense of speed, responsiveness to his actions. You can call it a golrified loading screen.
The listing on the right is the first functional page of the site, the first section that is loading
by default is the food section, this can be later changed on the settings page. From here on
the user can get anyhwere in the application, either by chaging the category, opening a venue,
searching for a venue, or accessing about and options page from the drawer.
DESCRIPTION - homepage and listing
Technologies
CODE STRUCTURE
webapp code structure top
to bottom
AngularJS
it is the backbone of the entire
application, no pun intended
Bower.io
A package manager for the
web. Provides vendor libraries
for the application(Angular...)
Karma TestRunner
Runs javascript sanity tests on
the apps code, not used yet, I
have to maketests for everythi
AngularJS
it is the backbone of the entire
application, no pun intended
MongoDB
is the permanent storage solution I am using for this application, saves JSON objects.
expressJS
node.js web application
framework, providing a robust set of features for node.js
Grunt TaskRunner
takes care of all the aspects of
the environment, build, versioning, deployment, compile
HTML5
using some APIs from it.
URLs etc.
Jasmine
language used to create tests
that are run by Karma.
Node.js
used at the moment like a
container to run the app. Will
use it for proper routing.
MongoLabs
Provides MongoDB as a service, and a RESTfull interface
to connect upon.
Heroku
The application is deployed
on a Heroku node.js application
Github
repository, project management, bug & feature reporting
service
PubNub
Realtime notification service.
Not used yet.
this is self
explanatory
CODE STRUCTURE
Project Scaffolding
This is the main project structure.
As a small starter, this application is kept together and
built by grunt, which relies on nodeJS, we also have a
lot of grunt add-ons that take care of automation for us
(clean, copy, jshint, concatenate, watch, uglify, karma,
ngmin, html2js, coffee, change log, bump and protractor, well be discussing this in the next chapter )
nodeJS server and its dependencies, grunt compiles automatically the source project and copies it in the production
environment, from there its pushed to heroku.
/src is our source files, where Im working in
/strippedLibraries is a folder where I am putting libraries that I will fully integrate into my app, unlike
the vendor folder (below) in libraries I have bits of only the code I need for my app.
/vendor is folder that is populated by bower with all the dependencies I specify in bower.json (angular:
-animate, -cookies, - hammer, -local-storage, firebase, lodash etc etc)
.bowercc tels bower where to install the dependent libraries, it has directory : vendor in it.
.bower.json is the reference point for bower, it contains app version and dependency libraries like
angular-ui-router: ~0.2.7
.build.config.js contains a set of references called by grunt when compiling the project, file locations,
build dir variables etc and a link to the vendor files
.CHANGELOG.md is self explanatory, after running to `grunt bump` to build a new version I run
`grunt changelog` to add a new entry in the change log which Im adding explanations to.
.Gruntfile.js is the main grunt file where all the grunt tasks are created and ran from.
.package.json is the file that contains the dependencies when running npm install, like grunt-contrib-uglify: ~0.2.7, it also contains versioning and other descriptor elements
Angular Scaffolding
Testing
I will describe the testing process summarily because I still need to start doing it :). The pragma here
is that for every file that we create, we need a appropriate test, the best approach would be start this
using Test Driven Development, we get an idea of the method/function, angular controller/directive/
service etc we want to make, then FIRST we create a basic test for it and we make the actual JS file in
tandem with the test file, the benefits are extremely obvious.
In our case, every *.spec.js file is ran through karma which tests the integrity of our code, the code is
tested in PhantomJS and the results are outputted in the console. IF we are using `grunt watch` the
tests will run constantly on file change events and the console will ping if theres an error in our code.
As a good practice, all the js code is parsed through jslint before build task, and we get realtime errors
and code hints in the console if our IDE is not set up the same as jslint
LESS
The great thing here is the organization of the files, we create separate less files for every template
which will be compiled in one big file for the production environment.
Dependency Injection
I think the best to describe dependency injection is by exemplifying a set of services I did last weekend.
As a pragma, AngularJS is build with dependency injection in mind. In our main app.js file we are calling the top tier of factory services, services, controllers and directives we need, and from there on we
specify further dependencies in those specific services/controllers.
Back to my example, I have created a middleware service, its called `storageManagement`, this service
needs other services to work, and the logic inside it is exposed through methods to be called upon in
our controllers.
As a dependency tree on HOW I connect to MongoDB and Firebase and USE the databases we have
the following diagram:
Zoom In
MongoDB
MongoLabs
MongoDB as a
Service
storageM.
calls
mongoService
storageManagement
firebase
library
AngularFire
middleware
Firebase DB
storageM.
calls
firebaseService
storageM.
calls
firebase
simpleLogin
INSIDE MY DOMAIN
OUTSIDE MY DOMAIN
Build Environment.
tivitys build environment is handled entirely by grunt. Grunt and its plethora of add ons take care of
the entire process regarding development build, production and testing. Grunt, as stated on their website is a task runner, with complementary modules, here, there is a system of tasks that run on every
build.
Lets take the build task, it uses the watch module, listening for a file change in a designated directory
and when a file has changed the following tasks are running:
grunt.registerTask( build, [
clean, html2js, jshint, coffeelint, coffee, recess:build,
concat:build_css, copy:build_app_assets, copy:build_vendor_assets,
copy:build_appjs, copy:build_vendorjs, index:build, karmaconfig,
karma:continuous
]);
clean - it cleans the directories where we will copy the compiled results
html2js - it takes all the partials and compiles them to js to reduce network calls and have them all in
one place, this does not happen in dev build, only in production build.
concat:build_css - takes all of our freshly converted CSS files and concatenates them into one, also
takes the vendor specific css libraries, if any (the external ones need path declaration in build.config.js
though)
copy:build_app_assets - copies all the assets to the new location, here we could insert the optimization hunt task
copy:build_vendor_assets - copies all the vendor referenced libraries in build.config.js, on production it also compiles everything into one file.
copy:build_appjs - on production it compiles all the files into one, and in development it just copies
the exact structure to the build folder.
index:build - it adds all the references to index.html, also this process is different from development
to production
Deployment Environment.
The deployment environment is a NodeJS application serves, with express as a dependency to create
all the required server side dependencies.
Everything resides in the production folder, there I have another git root that is connected to Heroku.
The application itself is copied here when we run `grunt compile`, as a result, in the `public` folder
well have the index.html, ONE javascript compiled file containing absolutely everything (app, routes
js, vendor libraries), and the assets folder.
A short description:
The rest of the files besides server.js are the same like above,
dependency fetching scripts.
There is also a Procfile that will get parsed when pushing
everything to Heroku so it knows what kind of server we
are running and runs the appropriate one.
MOBILE
mobile development concept (app-specific)
These are general guidelines by which I think a mobile web app should be developed, most of the
advice given here is not used YET in the application, as it is still a work in progress, but I have started
with these ideas in mind.
I hope I will get to the optimization part while developing this DEMO app, as much as times allowes
it, I am really eager to compare performance given all the subchapters below are applied to the application development.
HTML Optimization
Like I said in the opening bits of this document, a web app cannot be natively fast, even if the users
tend to believe this, therefore we need to actually lie to the user, showing him a sense of responsiveness even if we actually dont present him the information.
For this issue here the development of a web app should be centered around this pragma.
From a technological standpoint this means we have to server something to the user as quickly as
possible, this means:
- asynchronously loading js files so we dont interrupt the flow of the index loading.
- a bit of html and inline CSS that will load within the first second of access on the app
- if we dont have the templates in one file (html2js) buffered serving, a service that runs in the background and fetches all the necessities without interrupting application flow.
CSS Optimization
The CSS is paramount here, if we have default CSS then media-queryed CSS, the first CSS will load
nonetheless and then the media-query will apply the appropriate styles, for this, even the first CSS
should be in another media query that will just be skipped if the conditions arent met.
Another option to do this is to run a check first (with some default inline style for faster loading) for
which device do we want css and to make a network request for the appropriate file.
Bottom Line: load first some inline css for instant responsiveness, then fetch the required CSS file.
MOBILE - Optimization
Assets Optimization
What I talked about before, asset magnification and sprite-ification, if we have only a few small
icons, its better to load them in the html in base64, to avoid another network request.
JavaScript Optimizations
The main concern here is code size and what does the code do, in many cases pure JavaScript written custom for something leaves a smaller footprint, does exactly what we need it to do and if built
correctly, it runs fast, the lesson here is avoid using libraries from which you need only two or three
extensions.
Also, keep your interaction with in-browser objects to an absolute minimum, in our case Angular
takes care of that and it would be counter intuitive, and really, bad practice, to use jQuery to manipulate DOM objects.
Always use CSS animations where possible, JS animations are very costly on the resources.
This obviously implies code optimization, theres a bunch of articles on the matter, no point describing this here, improper function calls, closures etc.
Angular Optimization
Angular is wonderful. Im gonna start with that. But as with any other library if used improperly it
can cause you a lot of headaches.
We have to check the number of $watches, or if possible avoid it entirely (actually if build properly),
we can leverage the $digest run that angular does on every action to supplement for $watch.
I still have to learn a few things about optimizing Angular apps really good, but, in retrospective, I
try to keep with the best practices.
MOBILE - Optimization
Network Performance
The greatest enemy of a web app is the number of network request, even if we have a good speed, on
mobile devices through 3G a network request might take long that even fetching the file/asset.
The base ideas here are:
- serve as little as possible
- or at least serve at little as possible at the beginning to give the user a response
- compress files
- minimize files number
- if you are connecting to multiple RESTfull APIs create an external service that fetches all the data
at once from all your sources
MOBILE - Optimization
Github
github workflow
- versioning
grunt takes care of the versioning, its semantic versioning as need by git and like the most standards on the internet
- github
Nothing to say here
- github issues system
Github has a beautiful issues system, with labels.
The issues can be closed or updated directly from the commit message, e.g.: ` git commit -m
Fixes for firebaseService. Close #43 `