an introduction to the programming best practices for javascript and Titanium mobile
(cross platform programming seminar at university of pisa, july 2012)
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
Titanium appcelerator best practices
1. BEST PRACTICES
in apps development using
TITANIUM APPCELERATOR
Alessio Ricco
@alessioricco
1
2. Software Quality characteristic
(user point of view)
• Adaptability: is the app able to run in different environments ?
• Accuracy: how well does your app do the job ?
• Correctness: is your app able to do the job ?
• Efficiency: minimizing system resources
• Integrity: is your app secure ?
• Reliability: does it crash ?
• Robustness: does your app handle invalid inputs ?
• Usability: is it easy to learn how to use it ?
USERS notice STABILITY and PERFORMANCE
2
3. Software Quality characteristic
(developer point of view)
• Flexibility: can you adapt the app for other uses ?
• Maintanability: debug, improve, modify the app
• Portability: adapting the app for other platforms
• Readability: source code is easy to understand
• Reusability: using parts of your code in other apps
• Testability: the degree to which you can test the app
• Understandability: can you understand what the app does and how it
does it ?
DEVELOPERS needs RAPIDITY and READABILITY
3
4. Software Quality characteristic
User side:
STABLE
(applications must have a predictive behaviour)
PERFORMANT (speed must approach the speed of cpu)
Developer side:
RAPID
(development must be fast)
READABLE
(code must be easy to understand)
4
6. Avoid the global scope
• NO GARBAGE COLLECTION
In the global scope not null objects cannot be collected
• SCOPE IS NOT ACCESSIBLE FROM MODULES
app.js is not accessible within CommonJS modules
app.js is not accessible within other contexts (windows)
• Always declare variables
• Always declare variables inside modules or functions
• Assign global objects to null after the use
6
7. Nulling out object references
// create ui objects
var window = Ti.UI.createWindow();
var myView = myLibrary.createMyView();
win.add(myView);
win.open();
// remove objects and release memory
win.remove(myView);
myView = null;
// the view could be removed by the GC
7
8. Keep local your temp var
// immediate functions help us to avoid
// global scope pollution
var sum = (function() {
var tmpValue = 0; // local scope
for (var i = 0; i < 100; i++) {
tmpValue += i;
}
return tmpValue;
})();
// i, tmpValue are ready for GC !
8
9. Use self calling functions
// self calling function
(
function()
{
var priv = 'I'm local!';
}
)();
//undefined in the global scope
alert(priv);
9
10. Use namespaces
Enclose your application's API functions and properties into a
single variable (namespace). This prevent the global scope
pollution- this protect your code from colliding with other
code or libraries
// declare it in the global scope
var mynamespace = {};
mynamespace.myvar = “hello”;
mynamespace.myfunc = function(param) {}
10
11. Namespaces are extendable
// extend and encapsulate by using self-calling functions
(function() {
function helper() {
// this is a private function not directly accessible
! ! // from the global scope
}
myapp.info = function(msg) {
// added to the app's namespace, so a public function
helper(msg);
Ti.API.info(msg)
};
})();
// you could then call your function with
myapp.info('Hello World');
DON'T EXTEND TITANIUM NAMESPACES !!!!!
11
12. Understanding the closures
A closure is a function together with a referencing environment for the
non local variables of that function
// Return a function that approximates the
derivative of f
// using an interval of dx, which should be
appropriately small.
function derivative(f, dx) {
return function (x) {
return (f(x + dx) - f(x)) / dx;
};
}
the variable f, dx lives after the function derivative returns.Variables must
continue to exist as long as any existing closures have references to them
12
13. Avoid memory leaks in global event
listeners
function badLocal() {
// local variables
var table = Ti.UI.createTableView();
var view = Ti.UI.createView();
// global event listener
Ti.App.addEventListener('myevent', function(e) {
// table is local but not locally scoped
table.setData(e.data);
});
view.add(table);
return view;
};
Consider to use callback functions instead of custom global events
Place global event handlers in app.js
Rule : global events handle global objects
13
14. Lazy script loading
Load scripts only when they are needed
JavaScript evaluation is slow, so avoid loading scripts if they are not necessary
// load immediately
var _window1 = require('lib/window1').getWindow;
var win1 = new _window1();
win1.open()
win1.addEventListener('click', function(){
! // load when needed
! var _window2 = require('lib/window2').getWindow;
! var win2 = new _window2();
! win2.open()
})
BE AWARE: Some bugs could not be discovered until you load the script...
14
15. Cross Platform
BRANCHING
useful when your code is mostly the same across platforms but vary in some points
// Query the platform just once
var osname = Ti.Platform.osname;var isAndroid = (osname ==
'android') ? true : false;var isIPhone = (osname ==
'iphone') ? true : false;
// branch the code
if (isAndroid) {
// do Android code
...
} else {
// do code for other platforms (iOS not guaranteed)
...
};
// branch the values
var myValue = (isAndroid) ? 100 : 150;
15
16. Cross Platform: branch
// Query the platform just once
var osname = (Ti.Platform.osname == 'ipod') ? 'iphone' :
Ti.Platform.osname;
os = function(/*Object*/ map) {
var def = map.def||null; //default function or value
if (map[osname]) {
if (typeof map[osname] == 'function') { return
map[osname](); }
else { return map[osname]; }
}
else {
if (typeof def == 'function') { return def(); }
else { return def; }
}
};
// better than if statement and ternary operator.
var myValue = os({ android: 100, ipad: 90, iphone: 50 });
16
17. Cross Platform: JSS
PLATFORM-SPECIFIC JS STYLE SHEETS (JSS)
JSS separate presentation and code.
module.js
var myLabel = Ti.UI.createLabel({
! text:'this is the text',
! id:'myLabel'
});
module.jss
#myLabel {
! width:149;
! text-align:'right';
! color:'#909';
}
for platform specific stylesheets you can use module.android.jss and
module.iphone.jss, but module.jss have the precedence.
17
18. Images
Minimize memory footprint
Image files are decompressed in memory to be converted in
bitmap when they are displayed.
No matter the .png or .JPG original file size
Width Height Colors Footprint
320 480 24bit 450KB
640 960 24bit 1800KB
1024 768 24bit 2304KB
2304KB
2048 1536 24bit 9216
18
19. Image optimization
• use JPG for displaying photos- use PNG for displaying icons, line-art, text
• use remove() when the image is not visible on screen
• set image views to null once no longer need those objs
• resize and crops images to the dimensions you need
• resize images to minimize file storage and network usage
• cache remote images (https://gist.github.com/1901680)
19
21. Database
Close the database connection after insert and update
var db = Ti.Database.open('myDatabase');
try{
! db.execute('BEGIN'); // begin the transaction
! for(var i=0, var j=playlist.length; i < j; i++) {
! var item = playlist[i];
!
! db.execute('INSERT INTO albums (disc, artist, rating) VALUES
!
(?, ?, ?)', !! item.disc, item.artist, item.comment);
!
! }
! db.execute('COMMIT');
}
catch (e){
! Ti.API.info( "SCORE: error retrieving score [2]" );
}
finally {
! db.close();
}
21
22. Database
Minimize your database size
• Big Databases increases your app package file size
• The database is duplicated on your device because is copied to the
ApplicationDataDirectory
• On some Android releases the installer cannot uncompress assets over 1MB (if
you have a 2MB database you need some workarounds)
Keep your db small and populate it on the 1st run !
read sql-lite FAQ:
http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html
22
23. Style and convention
Learn and follow language rules, styles and paradigms
javascript
isn't c# or java or php
titanium appcelerator is not just javascript
Follow coding style best practices
Naming Conventions
Indentation
Comments Style
Follow language related communities and forums
don't reinvent the wheel
learn community best practices
23
24. Language Rules
Learn and follow language rules, styles and paradigms
javascript
isn't c# or java or php
titanium appcelerator is not just javascript
Follow coding style best practices
Naming Conventions
Indentation
Comments Style
Follow language related communities and forums
don't reinvent the wheel
learn community best practices
24
25. Language Rules
Always declare the variables
When you fail to specify var, the variable gets placed in the
global context, potentially clobbering existing values. Also, if
there's no declaration, it's hard to tell in what scope a variable
lives.
So always declare with var.
25
26. Language Best Practices
Use the Exactly Equal operator (===)
comparing two operands of the same type is, most of the
time, what we need
var testme = '1';
if(testme == 1) // '1' is converted to 1
{
! // this will be executed
}
var testme = '1';
if(testme === 1) {
! // this will not be executed
}
26
27. Language Best Practices
Is better wrap self functions with parenthesis
var myValue = function() {
//do stuff
return someValue;
}();
// the same code, but it's clear that
myValue is not a function
var myValue = (function() {
//do stuff
return someValue;
})();
27
28. References
Titanium Appcelerator online documentation
http://docs.appcelerator.com/
Code Complete 2nd Edition – Steven C. McConnell - Microsoft Press
http://www.cc2e.com/Default.aspx
SQLite Optimization FAQ
http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html
Douglas Crockford
http://javascript.crockford.com/
Google Javascript Style Guide
http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml
TwinsMatcher
http://itunes.apple.com/app/twinsmatcher/id429890747?mt=8
@alessioricco
http://www.linkedin.com/in/alessioricco
28