This documentation relates to previous versions of Titanium.

To see the latest documentation, visit docs.appcelerator.com.

Skip to end of metadata
Go to start of metadata

Objective of the Guidelines

Titanium Mobile is a relatively young and constantly changing platform. The best practices delineated here are subject to change, and may not encompass all the knowledge necessary to build a great Titanium application. The goal of this document is to lay out, at a high level, what are currently known to be good (and some bad) practices in Titanium Mobile (and JavaScript in general) applications.

The Guidelines in Brief

Titanium Mobile applications should:

  • Be careful not to pollute the global object
  • Run in a single JavaScript context
  • Be modular and object-oriented using CommonJS modules
  • Defer loading JavaScript files until absolutely needed
  • Take reasonable steps to manage memory usage and avoid memory leaks

Seriously? That's it?

Yes. There are many different ways to build an application - using an MVC or MVVM architecture, maybe a framework of your own choosing or one you've built yourself. The guidelines in this document are considered the bedrock requirements for a stable and performant Titanium Mobile application. Your own application structures, business logic, and conventions may vary, and we do not endeavor to impose any such conventions in this document.

The Guidelines Explained

Applications shall take care not to pollute the global object

In JavaScript, there is a global object for the application - any variables declared in the global scope will become properties of this global object. In Titanium Mobile, the global object is available as this in app.js.

Any variables declared in app.js shall be globally available in the entire application. This can cause collisions if external scripts are included into this context via Ti.include. For this and other reasons, use of Ti.include is discouraged, and will be replaced in the future by the CommonJS module specification's require function.

To prevent polluting the global object in app.js, you must use the only scope available in JavaScript - a closure. A simple way to use a closure to avoid polluting the global scope is to use a self-calling function:

app.js

When separating code into external files, the require function provided by the CommonJS module spec should be used to inject additional functionality into the global scope or the scope of a module. This technique will be explained later on in the document.

Applications shall run in a single JavaScript context

In the previous section, we discussed the global scope of a JavaScript application. With Titanium Mobile, it is possible to create a window with a url property set to a path to a Javascript file (relative to the current file). When the window's open method is called, the associated JavaScript file is evaluated, creating a secondary "execution context" and, thus, a new scope. Except in rare cases, this multiple active JavaScript environment should be avoided.

These multiple execution contexts cause problem because no scope has visibility of any other, meaning that sharing data between contexts is not possible without the ungainly use of application-level custom events (using Titanium.App addEventListener and fireEvent). They can also lead to circular references and likely memory leaks. There are lifecycle issues too, where it becomes unclear when the code for a given JavaScript file has been evaluated.

While there are a few reasonable use cases for this approach, such as an "app within an app" where every new window requires a "clean slate" with no dependencies on the global context, normally windows with URLs should not be used.

Applications shall be modular and object-oriented using CommonJS modules

Separation of concerns should be enforced by dividing application logic into separate JavaScript files and objects, adhering to the principle of cohesion. Not all JavaScript applications need to use instantiable objects - but all should make use of the CommonJS module standard. The CommonJS module spec provides for sandboxed JavaScript modules with a well-defined public interface, exposed as the exports object within a CommonJS module file. A sample usage of the CommonJS module spec in Titanium Mobile is below.

A simple CommonJS module, in lib/maths.js in the Resources directory
Sample usage in app.js

An instantiable object in a CommonJS module would look like this:

lib/geo.js - A module containing instantiable objects
Sample usage in app.js

When creating objects in Titanium Mobile applications, one must adhere to general programming best practices, including object orientation. In this section, we will go into one more example. A common need in Titanium Mobile applications is to create custom user interface components. A common practice for extending built-in objects is parasitic inheritance. While a perfectly valid practice in standard JavaScript, it can result in unpredictable behavior in Titanium Mobile when using proxy objects (objects returned by Ti.UI.createView and similar). A reasonable approach to creating a custom component would be to associate a proxy with a normal JavaScript object, as in the below:

ui/ToggleBox.js - A custom check box
Sample usage in app.js

Applications shall defer script loading until absolutely needed

One of the bottlenecks of a Titanium application is JavaScript evaluation. This is particularly the case for Android, although the V8 runtime provides substantial improvements for this issue compared with Rhino. For that reason, to speed the startup and responsiveness of your application, the developer should avoid loading scripts until they are absolutely needed. As in the following application, which has three windows to be opened in succession on a click (touch) event, note that the dependent JavaScript for each window is not loaded until absolutely necessary.

Lazy script loading in app.js

Applications shall take reasonable steps to manage memory

In very large applications, it occasionally becomes necessary to force Titanium to clean up resources. To do this, the developer has a few things to track:

  • the windows can be closed. This should cause Titanium to free up the resources reserved for the view objects added to the window.
  • remove global event handlers when they are no longer needed. References to objects within these closures will be retained otherwise - this is a common memory leak in large JavaScript applications in the browser also. Some common global event handlers include Ti.App.addEventListener (global messaging system), geolocation events, and orientation change events
  • proxy objects can be set to null. This ensures that these objects are garbage collected to release the associated native objects.

Example:

Nulling out object references
Labels
  • None