The model

August 26th, 2009

The database

The model of the application has been built with the specifications of the project in mind and the will to make it future-proof. Although it was only supposed to support an application used for managing presentations, creating/editing slides and playing presentations, it seemed sensible to enable, in its design, features such as revision control, collaboration as well as the possibility to store different kind of documents in the application. The following criteria have been considered

  • in order to make the model more generic, it is designed for “multi-parts documents”, rather than “presentations composed of slides”,
  • the different parts of a document are split to make it possible to load only the parts of the document that the user needs (lazy loading),
  • the HTML terminology is used to designate those “multi-parts documents”, a document being an <article>, which is composed of an unlimited number of <section>s
  • a document has a unique creator, a user registered in the application, although it might later have multiple authors if collaboration is to be enabled,
  • there are no folders in the application, but presentations can be tagged with an unlimited number of tags and later sorted by tags,
  • the bin is just a tag which, when applied in a document, prevents it to be displayed in the main view,
  • a document can have a theme, which is stored as a style (using the CSS format) that will be applied to all of its parts
  • additionally a document can be associated with a piece of script describing its background as vector graphics for example (to be translated either to SVG or VML)
  • a section of a document has an HTML content, a style to overwrite the theme of the document and define the layout of the content, as well as a piece of script used to represent its vector graphics content in a browser agnostic way,
  • the script, the style and the html content are split to make version control easier (details follow)

This description of the model can be graphically represented as follows:

About the version control

Version control would be easy to implement with this model because it makes creating a new revision of the document inexpensive: when the content of a single section is modified, instead of duplicating the whole document, a new version of the this specific content is created, and only the representation of the document and the sections are duplicated, not their unmodified content. This mechanism is illustrated in the following figures.

Since there is no content at all directly in those representations, the database does not expense at an exponential rate. The elements coloured in red in those figures are the ones potentially heavy weight.

The way the revision control could be implemented is rather clear: to restore a previous revision, a relation between the user an the previous revision (found through the current revision) has to replace the current relation.

Developer friendly technologies

August 26th, 2009

Since ToDoSo is a too important project for a single person, it appeared as important for its underlying technologies to be easily learned by external developers willing to contribute to the project.

Being a Web application, the choice is naturally limited to Web technologies and the project will likely drive the interest of developers with technical skills related to the Web.

The client-server relationship on the Web

The Web is a particular platform to work on, since it is strictly divided in two parts:

  • the server side, which refers to the part of the application hosted on a server,
  • and the client side, which refers to the part of the application that is executed directly in the Web browser of the users.

Originally, this client-server relationship was described as a thin-client: the server being the host of all the logic of the application while the client, in this case the Web browser, was a rather passive one, only able to request an URL, process the incoming HTML code into what the user knows as a Web page and sending back a request (sometime with form data) for a whole new page. Since the introduction of JavaScript in the Web browser, they evolved in smarter clients now able to dynamically and partially update the page ― known as ajax techniques (Paulson, 2005) ―, turn static Web pages into rich user interfaces ― gmail often being quoted as the pioneer of Web applications (O’Reilley 2007) ― and even use them for distributed computing (Klein and Spector 2007).

Client-side technologies

As it has already been mentioned, in addition to HTML and JavaScript, other client-side technologies are available as plugins for Web browsers, such as Flash and Silverlight. Not only have the latter ones a limited accessibility, but Web developers are also more likely to be familiar with the still prevalent Open Web technologies.

The obvious advantage of those plugins is that they provide a consistent environment across the variety of configurations that they support: a website built for Flash will be displayed exactly the same way in Internet Explorer 6 on a Windows computer as in Safari 4 on a Mac OSX computer. There are, however, numerous inconsistencies between configuration that have to be dealt with when using Open Web technologies:

  • There are different browser vendors with different implementations of HTML rendering engine and JavaScript engine. All of them are supposed to follow the w3c recommendations for HTML, CSS and the DOM interface as well as the ECMA-262 standard for JavaScript. Due to the complexity of those recommendations, the difficulty for all browser vendors to agree on them and their constant evolution ― not even mentioning the so called browser war between Microsoft and Netscape in the late 90’s (Phillips, 1998) and backward compatibility issues ―, there are unavoidable differences between the way a single Web page is interpreted in two different Web browsers, either because of an incorrect, incomplete or flawed implementation.
  • There can be different versions of a browser in use at a given time. According to Net Applications, there are currently 27% of Internet Users using IE6, 23% using IE7 and 12% using IE8. If an implementation is improved or fixed in the new version of a browser, it is therefore impossible to assume that all users will benefit from it.
  • The fonts that can be used in a Web page is still limited to the ones available in the rest of the Operating System and the displaying of the text relies on the OS capabilities. This can result in differences in the width and height of textual elements.

Dealing with JavaScript

JavaScript is the most consistent technology of this set. Although some browsers implement more recent versions of the standard, all current browsers comply with the version 1.5 of the norm, which has proven to have appropriate features for large scale Web applications.

Dealing with the DOM

In order to deal with DOM inconsistencies as well as simplifying common operations on Web pages, numerous JavaScript libraries (sometime named toolkits or frameworks) were created, the most widespread ones being Dojo, Prototype, YUI, jQuery and Mootools.

There does not appear to be any objective comparison of these different libraries in the literature. Indeed, being Open Source software, they have influenced influenced each other to a point where it is difficult, if not impossible, to pick one as the best. Their common traits are:

  • simplifying DOM traversing and manipulation, i.e. inserting, finding, moving and deleting elements of a Web page,
  • simplifying the modification of elements’ attribute such as class or style attribute to dynamically change the appearance of an element,
  • providing methods to change the style attributes of an element over time to animate it,
  • providing an unified API for ajax instead of the one implemented in w3c compliant browsers and its counterpart in Internet Explorer,
  • providing an unified API for event handling (i.e. detecting a user’s actions on a page) instead of the one implemented in w3c compliant browsers and its counterpart in Internet Explorer and providing helpers to deal with event delegation.

The library of choice for this project is jQuery, because of its clean API, its light weight and its thorough documentation. The jQuery philosophy is unofficially summarized in “Find things, do stuff“: The page is queried with a CSS selector (a mechanism that every Web developer is familiar with) and the selected elements can then be manipulated using jQuery methods.

$("#myButton").click(function() {
	$("<span>Hello World!</span>").hide().appendTo("#myParagraph").fadeIn();
});

The previous snippet of code illustrates the different possibilities of jQuery, its conciseness and the principle of chainability: once an element has been selected in the page, different operations can be applied at once. It reads as follows:

  1. find the element with an id “myButton”,
  2. when it is clicked executes the following…
    1. create a text wrapped in a span element (this is an HTML syntax),
    2. make sure it is hidden …
    3. … before appending it to the element with the id “myParagraph”,
    4. gradually modify its opacity from 0 to 100%.

Although there are no clear statistics of the usage of the different libraries, the growing popularity of jQuery amongst Web developers, illustrated by its inclusion in the set of tools distributed with Microsoft’s Visual Studio IDE, as well as its documentation is expected to make it easier for external developers to contribute to the implementation of the client-side part of ToDoSo.

Dealing with CSS

CSS is the languages that suffers the most inconsistencies on the Web. In their latest versions, all browsers appear to be compatible with a large subset of CSS2.1, but as outlined previously, there are still around 50% of Internet users browsing the Web with older versions of Internet Explorer.

A simple solution would be to enjoin users of old browsers to update to the latest version. However, in a recent survey lead by digg, one of the largest social news Website, it appeared that 70% of those users are using IE6 because they are not allowed to install a different browser on their computer[1. Much Ado About IE6 ]. Although this number cannot be generalised, it tends to indicate that ToDoSo should be compatible with IE6 to be accessible to most users. Since ToDoSo is not expected to be publicly available before several months, a compromise could be to ignore versions of IE prior to 8 during the development phase (developers are likely to have up to date browsers) and reconsider the compatibility with older versions of IE later. Their usage share might have decreased to a point where they could definitely be ignored.

Server Side Technologies

Unlike on the client-side, there is a large variety of languages and frameworks available on the server-side to build Web applications. If any environment can be used on the server-side to create Web applications, Ruby on Rails lately pioneered the field of agile Web frameworks which seem to seduce more and more Web application developers.

The Agile Manifesto defines four leading principles (Cockburn, 2002):

  • Individuals and interactions over processes and tools
  • Working software over comprehensive documentation
  • Customer collaboration over contract negotiation
  • Responding to change over following a plan

A framework that actually allows for working prototypes to be rapidly built and for changes to be answered quickly would be highly valuable, for ToDoSo is expected to become a project opened to external contributions. The choice of server side technologies was thus limited to frameworks that shared some of the key features which make Ruby on Rails an agile framework.

  • Model-View-Controller architecture
  • Object Relational Mapping
  • CRUD for all objects
  • Routing mechanism
  • HTML templating

A simplified explanation of this technical jargon is possible with a sample pseudo-code application: a Website that allows users to view the relationships between three people: Louis, Remi and Eugene.

MVC Architecture

This design patterns makes a clean separation of the application in three layers:

  • the model defines what a person is, what relations it can have, and how those different properties are remembered in the application
  • the view in this case is the HTML page used to display the people and their relations,
  • the controller is the logic that answers to users’ requests by recalling people and relationships from the application’s memory and invoking the appropriate view to display them.

The model

// A person is defined by its name and its gender
Person = isDefinedBy({ name: "String", gender: "Boolean" });
// A person can have a relation of friendship with another person
Person.canHave( "friend", Person );
// A person can have an enemy
Person.canHave( "enemy", Person );

Once the memory of the application contains some person, the controller can retrieve them and pass it on the the view to produce the following output:

<p>
	<b>Louis</b> is a <em>male</em>.
	His/Her friend is <b>Remi</b>.
	His/Her enemy is <b>Eugene</b>.
</p>

Such a clean separation makes modifying one of those layer safer and easier.

Object-Relational Mapping

Traditionally the people and their relationships would require two different representations in an application built with an object-oriented language and a database, typically using either Classes or SQL queries. In such paradigm, making Remi a friend of Louis is a rather complicated task:

// Insert a Person in the database and returns its assigned id
function insertPerson( name, gender, friendId ) {
	DB.execute(
		"INSERT INTO 'person' ( 'name', 'gender', 'friend_id' )" +
		"VALUES ( '" + name + "', '" + gender + "', '" + friendId + "' );"
	);
	return DB.lastInsertId;
}
// Build Remi first
remi = new Person({ name: "Remi", gender: 1 });
// Save him
idRemi = insertPerson( remi.name, remi.gender );
// Then build Louis
louis = new Person({ name: "Louis", gender: 1 });
// Save Louis while making him friend with Remi
idLouis = insertPerson( louis.name, louis.gender, idRemi );
// And later...
// Find Louis' data in the database
data = DB.execute( "SELECT ALL FROM 'person' WHERE 'id' = '" + id + "';" );
// Recreate Louis from its data
louis = new Person({ name: data.name, gender: data.gender, data.friend_id });

Using an Object-Relational Mapping layer, the database is abstracted away and relations defined between two objects of the model can be applied directly between Louis and Remi.

// Build and save Remi
remi = new Person({ name: "Remi", gender: 1 });
remi.save();
// Build Louis, make Remi his friend and save him
louis = new Person({ name: "Louis", gender: 1 });
louis.make("friend", remi);
id = louis.save();
// And later...
// Recreate Louis from the database
louis = Person.findById( id );

CRUD for all objects

CRUD stands for Create, Read, Update and Delete which represents the basic operation required for the complete life-cycle of an object in the application. In agile frameworks, once an object is defined in the model, it is automatically possible to use “create”, “update” and “delete” methods on every person, “read” being available on the Person object.

// Build Louis
louis = new Person({ name: "Louis", gender: 1 });
// memorise Louis <=> Create
id = louis.save();
// Turn Louis into a female
louis.set("gender", 0);
// Make sure this change is memorised <=> Update
louis.update();
// Get rid of Louis <=> Delete
louis.delete();
// Try to find Louis in the memory <=> Read
Person.findById( id );

Routing mechanism

This mechanism allows for urls to be mapped to specific actions of the controller. For example, when visiting http://myapp.com/person/1, an Web page with the details of the person that has the id 1 should be displayed to the Internet user.

personController = new Controller(function( id ) {
	// Fetch data from the memory
	data = Person.findById( id );
	// Pass it on to the view
	personView = Views.invoke( "person.html" );
	personView.pass( data );
});
personController.mapTo( "/person/:id" );

HTML templating

A template engine makes it possible to put place-holders for data of the model directly in an HTML document. Those place-holders are then replaced by the data fetched by the controller before being sent to the client.

The following template would be used to produce the aforementioned view output:

<p>
	<b><? data.name ?></b> is a <em><? data.gender ?></em>.
	His/Her friend is <b><? data.friend ?></b>.
	His/Her enemy is <b><? data.enemy ?></b>.
</p>

The related controller being:

personController = new Controller(function( id ) {
	// Fetch a person from the memory
	person = Person.findById( id );
	// Find his friend
	friend = person.getRelated( "friend" );
	// Find his enemy
	enemy = person.getRelated( "enemy" );
	// Build the data to be passed to the view
	data = {
		name: person.name,
		gender: person.gender,
		friend: friend.name,
		enemy: enemy.name
	}
	personView = Views.invoke( "person.html" );
	personView.pass( data );
});

Choosing an agile Framework

After spending some days looking in the literature and on the Internet, the selected frameworks were Ruby on Rails, Django (Rails’ python counterpart), Symfony (for PHP), Grails (for Java) and ActiveJS (for Jaxer).

Once again, it appeared impossible to pick one as the best. ActiveJS was finally selected for ToDoSo because, despite its lack of maturity compared to other frameworks, it had numerous features that was likely to make it easier for external contributors to adopt it:

  • it is meant to be executed by Jaxer, which is basically a Web browser stripped from its rendering engine to run on the server side. Web developers can thus leverage their client-side skills on the server-side with the possibility:
    • to access and modify the DOM on the server before it is sent to the client,
    • to share code between the client and the server sides (for safe but instantaneous form validation for example),
    • to call server side function from the client side (using invisible ajax requests)
  • it offers an abstraction not only to MySQL and SQLite databases (on the server-side) but also to client-side persistence such as Google Gears
  • its has a routing component similar to the Ruby on Rails’ one but also offers deep linking on the client side (enabling the use of the browser’s “back” button in ajax based Web applications)

Any developer able to use Open Web technologies would then find a familiar and consistent environment to work both on the server and the client side.

Aiming for Accessibility in a Presentation Software

August 24th, 2009

Since none of the existing on-line presentation software has been found to be accessible to keyboard navigation and screen reader users, none of the Web technologies used in this applications (HTML, Flash or Silverlight) clearly stands out as the technology of choice to achieve accessibility in a presentation software. A deeper comparison of has thus to be undertaken.

What makes an application accessible?

Accessibility is a general term used to describe the degree to which a product (e.g., device, service, environment) is accessible by as many people as possible.

Wikipedia, The Free Encyclopedia

It is important to note that accessibility concerns are not oriented only oriented toward people with disabilities in its common sense. To some extent, everybody has some disabilities when it comes to using a computer application: most elderly people don’t have heavy sight problems but they might just be reluctant to use them because of the technological barrier, children might prefer to go out and play football rather than seat in front of a screen, businessmen might be using a mobile device with a small screen without a real keyboard… The finiteness is anyway a handicap shared by all humans: there is so much to do, so little time.

To the variety of individuals corresponds a variety of expectations against which the accessibility of the application will be evaluated: the elderlies are likely to prefer simplified software, children might be more keen on the ones that are enjoyable, whereas professionals are looking for powerful applications that do not make them waste their time. Accessibility can thus encompass notions such as usability, hedonistic, usefulness. From this point of view, technologies that help produce highly visual and dynamic applications might, for a particular user target, be the most accessible ones, despite their lack of compatibility with screen readers.

What makes a presentation software accessible?

A presentation software is multiform: it consists of different interfaces to manage, display and edit presentations, as well as the documents themselves. No claim of accessibility could be made unless both the interface and the content are accessible.

User Interface Accessibility

In all studied software packages, the main purpose of the management interface as well as the player is to allow the user to navigate through a set of documents or the different parts of a document. This navigation is usually possible both by using a pointing device and clicking on navigation buttons (play this presentation, display the next slide) or by using keyboard alternatives. The three aforementioned Web technologies all offer mechanism to make those controls accessible to visually impaired users: in all cases, text alternatives can be assigned to the buttons by the developers and this text as well as other textual elements of the page can be read aloud by screen readers.

The main purpose of the authoring part of a presentation software is to allow users to compose a slide by placing different kinds of elements (titles, bullet-points, quotations, images, graphs) in a particular layout. As pointed out in the project specifications, an important part of the information in presentations is carried out visually. It might be possible to create a presentation authoring tool specially for visually impaired users. Adapting a traditional one to those users seems however almost as challenging as adapting a drawing package for blind users, the issue here being rather a matter of usability than a technical one.

To be able to provide a pleasant navigation in the application, the underlying technology should allow for smooth effects (fade transitions, position animation) to be applied to the User Interface. Flash has always been famous for its animation capabilities, which are extensively used in on-line advertisement or in-browser games. Silverlight has been conceived to have equivalent capabilities notably in term of animations and visual effects (Paries, 2008). It is now possible to animate HTML documents as well, thanks to JavaScript libraries such as Scriptaculous, jQuery and Mootools, resulting in visually attractive Websites that would have been realised with Flash yesterday.
There is a lack of comparison of the animation possibilities and performances of those three technologies in the literature. It is thus hard to guess if the effects will always be smooth and not exceed the resources of low-end hardware.

Content Accessibility – Text and Images

As pinpointed in the project specifications, the nature of information in a slide is textual and visual. If the text is accessible to visually impaired users through assistive technologies and to Web crawlers, the purely visual information is not.

Although it is possible to provide textual alternative for non-textual content using Flash or Silverlight, there is no way to preserve the distinction between titles, paragraphs, bullet-points and quotations.

In HTML however, the content is surrounded by semantic tags, i.e. indications about the nature of the text. The following slide…

A screenshot of a slide with a title, a bullet-point and a quote

… could be written as follows in HTML4 …

<div class="slide">
	<!-- The title of the slide is a heading of second level -->
	<h2>A Cat's Guide to World Dominashun</h2>
	<!-- bullet-points are nested in an Unordered List... -->
	<ul> <!-- ...as List Items  -->
		<li>Be careful, some are laready suspicious:</li>
	</ul>
	<!-- The following tag is rather self-explanatory -->
	<blockquote>
		In ancient times, cats were worshiped as gods.
		They have never forgotten this.
		― Terry Pratchett
	<!-- this tag indicates the end of the quote -->
	</blockquote>
<!-- note the / at the begining of the closing tags -->
</div>

This added structure and semantic is used by the screen reader which will state, while reading the content, that the first line is a heading, the following is a bullet point, followed by a block-quote, etc… Using a screen reader, it is also possible to jump from heading to heading using a keyboard shortcut and to use possible internal links to access directly the navigation menu. When the query “world dominashun” is typed in Google, the first results will be pages that have those two words in their headings, because they have a higher importance than if they were used in a paragraph.

In HTML4 there are no semantic tags that could be used to represent a slide or a presentation. The HTML5 propositions introduces new ones including the section and the article tags:

The section element represents a generic document or application section. A section, in this context, is a thematic grouping of content, typically with a heading, possibly with a footer.

The article element represents a section of a page that consists of a composition that forms an independent part of a document, page, or site. This could be a forum post, a magazine or newspaper article, a Web log entry, a user-submitted comment, or any other independent item of content.

The section tag seems appropriate for the slides and the article tag seems appropriate for the presentation. All current browsers but Internet Explorer are able to deal with unknown tags. In the latter, a special script has to be used before being able to style the elements. Those elements are not yet recognised by assistive technologies either and are currently ignored.

Content Accessibility – Vector Graphics

In addition to text and image elements, users should be able to use vector graphics to create chart and diagrams in a slide. This would effectively make ToDoSo useful for a large variety of professional users.

Vector Graphics are traditionally the prerogative of Flash as browser vendors never agreed on a common standard. Despite being not interoperable, all browsers have native vector graphics capabilities which integrates with HTML. Just like Flash, Silverlight provide the possibility to create and manipulate vector graphics.

Conclusion

Although Flash and Silverlight seem to be appropriate technologies to make ToDoSo accessible to its average target users, they fail to make the content of the document accessible to visually impaired users as well as Web crawlers. Moreover, those two technologies requires the client to have an additional plugin installed on its computer and those plugins are not available for all configurations (see project specifications). HTML5, on the other hand, would allow for the whole application but its authoring part to be accessible to people using assistive technologies and/or keyboard navigation. Thanks to JavaScript, it is now possible to apply rich visual effects on HTML content and use browser native capabilities to render vector graphics, effectively aligning the Open Web technologies with the other rich multimedia technologies of the Web.

Practical Performances in Web applications #1: Making it faster

August 24th, 2009

Important notice: the following post is likely to be largely modified in the next days due to the importance of this topic in the scope of my Master project.

An obvious criteria of usability for an application in general is its performances. This criteria encompasses the initial load time of the application and the potential transitions time between the different states of the application (e.g. the different screens of a desktop applications or the different pages of a Website). There are two complementary ways to tackle it:

  • identifying the technical parameters involved in the length of those load times and taking actions to make the application faster,
  • identifying the psychological factors of perceived performance by the user and taking actions to make the application feel faster.

Making the application faster

Over the past decade, performance on the Web is an area that gained an increased attention as Websites moved from static text-based content to dynamic and multimedia Web applications. The literature is an important source of information about back-end performances, informing about the different servers (e.g. Hu et al 2007), architectures (e.g. Barroso et al 2003) and patterns (e.g. Pyarali et al 1999).

Lately, majors actors of the Internet including Yahoo and Google started to advocate front-end optimisation as an easy and effective way to achieve performances on the Web. Yahoo published guidelines for “High-performance web sites” (Souders 2008 and its online and more up-to-date conterpart: Best Practices for Speeding Up Your Web Site) along with a browser plugin which measures the performances of a Web page against those guidelines: YSlow.

The approach adopted in ToDoSo was to delegate the responsibility of back-end optimisation by using a cloud computing service and an existing Web application framework, while concentrating on front-end optimisations using Yahoo’s resources.

Back-end performances – the infrastructure

One of the fastest growing trends about Web infrastructure during the past two years seems to be the cloud computing.

Cloud computing is a style of computing in which dynamically scalable and often virtualized resources are provided as a service over the Internet. Users need not have knowledge of, expertise in, or control over the technology infrastructure in the “cloud” that supports them.
Wikipedia, the Free Encyclopedia

In the case of Web applications such as ToDoSo, it allows project managers to rely on a third’s expertise in building, refining and maintaining an efficient infrastructure which will run the application in optimal conditions.

In addition to the enterprise-oriented cloud computing offers (see DELL, Sun Microsystems, Microsoft, IBM, Joyent and Vmware services), there are now more affordable solutions aimed at developing projects such as Amazon EC2, Google App Engine, Engine Yard and Aptana Cloud.

The latter has been chosen in ToDoSo…

  • because it is based on Joyent services, which is a guaranty that the infrastructure will be able to scale with the application until it becomes the next Facebook,
  • because of its low starting price ($0.027/hour, second only to Google’s free plan),
  • because of its large variety of preconfigured environments (PHP, Java, Jaxer, Rails, Python) which makes it possible to switch easily if the first choice proves to be a bad one,
  • and because of its tight integration within the Integrated Development Environment used throughout this project ‒ Aptana Studio ‒, effectively reducing the complexity of the deployment.

Back-end performances – the development Framework

Performances were not a key factor when it came to choose the development framework for ToDoSo. There is a vast choice of existing frameworks for Web applications; producing an objective comparison of their respective performances would have therefore required a tremendous amount of work that this project could not obviously afford. The choice was limited to the Open Source frameworks available on the chosen infrastructure and was actually based on the gentleness of their learning curve. Additional details are provided in the section related to “Developer Friendly technologies”.

Being Open Source software, it would be possible to fine-tune the application on different levels later in the development process, if required. It should also be noted that the less expensive cloud computing service for the Microsoft .Net platform appeared to be Amazon EC2, starting at $0.125/hour, i.e. 460% the price of the first plan in Aptana Cloud.

Front-end performances – Yahoo guidelines

Yahoo’s “Best Practices for Speeding Up Your Web Site” is a set of 34 best practices which can significantly improve the speed and responsiveness of a Web site. The following part describes which have been applied to ToDoSo and how.

These rules can be summarized into “reduce the amount of external resources to download”.

For that purpose, RockstarApps provides the JsLex plugin for Aptana Studio. Once installed, <link> or <script> tags can simply be selected from the source of a Web page; a dedicated options in the right-click menu can then be used to concatenate, minify using YUI Compressor and archive in gzip the source files all at once, while the selected tags are replaced by a single one pointing at the new optimised resource.

These rules can be summarized in “improve the external resources download speed”.

A [CDN] is a system of computers networked together across the Internet that cooperate transparently to distribute content for the purposes of improving performance and scalability.
‒ Wikipedia, the Free Encyclopedia

Just as for cloud computing, there are enterprise-sized CDN, the most famous one being Akamai as well as solutions adapted to smaller projects. Amazon offers two services, Simple Storage Service (Amazon S3) and CloudFront, which, once combined, constitute a CDN with no minimal fees and a competitive pricing: according to Bob Buffone, the monthly cost for a Website receiving more than 200 visitors a day is around $0.151.

There is another Eclipse plugin for Amazon Web Services by RockstarApps which allows Web developers to upload static resources to Amazon S3. The gzip compression must be applied before uploading the resources on S3 since, being a passive server, it does not archive files on the fly. Appropriate headers must therefore be set on the files (”content-type: text/css” and “content-encoding: gzip” for a CSS, “content-type: text/javascript” and “content-encoding: gzip” for a JavaScript), which is automatically done for files with the extension “.css.gz” or “.js.gz” by the plugin. In Safari and Google Chrome however, the extension takes precedent on the headers; the .gz suffix has therefore to be removed, which is not possible in the current version of the plugin.

Yahoo developed its own image optimisation tool in accordance to this guideline, smush.it, which can be used directly from within the YSlow plugin. As of July 2009, Gracepointafterfive developed their own tool, punypng, claiming for their state of the art solution to be second to none. Although no benchmarks have been produced by independent testers, the early results exposed by the creator of the tool seemed encouraging enough to justify its use for ToDoSo.

During the development of the different prototypes of this project, JavaScript already proved to be of a major importance in the operation of the Graphical User Interface. The library of choice for this project was jQuery, a lightweight piece of JavaScript (about 19KB once minified and archived) with a clean and easy to learn API making DOM traversing and manipulation, event handling, effects and ajax implementation a breeze. An important documentation and optimisation work has been undertaken to use the library in compliance with those guidelines.

  • Finally, some instructions have been ignored because either because they were not relevant to the chosen development framework (e.g. Flush the Buffer Early) or because the problem they were dealing with did not appeared in ToDoSo (e.g. instructions related to the use of cookies or iframes)

Conclusion

By getting familiar with simple rules that have then been applied during the development of the application, choosing affordable cloud computing and CDN solutions and using few simple tools aimed at front-end performances improvements, the load time of the project’s home-page is now inferior to 2 seconds despite the dozen images displayed on it.

It should however be noted that some of those strategies have not yet been applied to the two online prototypes, since they are early previews that will be vastly modified before being usable in real conditions.

Improved readability

August 23rd, 2009

Since I’m producing rather long posts these days (and there are more to come), I figured out that some adjustment in the the layout of the pages would be more than welcome.

Nothing has changed on the home page, but when clicking on the title of a post (or following the links in a feed reader), the new width, line-height and font-size should prevent the “there’s-no-way-I’m-reading-that!” effect.

This is Not the End

August 21st, 2009

It’s actually only the beginning.

ToDoSo is slowly moving to Aptana Cloud: the website first, and… the first version of the server as well!
Be kind with it, it is still very young. There is no point in mentioning that it is a prototype that needs a lot of work.
What it needs more than anything is care.

The next week or so will see no development of the application itself but many posts on this blog, as I’m writing the final report of my Master.

The Profiling Beast

August 21st, 2009

Profiling at 1am is hell.

Event delegation with jQuery1.3

August 20th, 2009

The ability to bind event listeners to DOM elements using JavaScript is a feature that is the base of elaborated interactions in Web pages. Using this mechanism, it is for example possible to submit a form, load another page or updating the current one when a user clicks on a specific button.

Simple events

The code required to bind a single listeners to an element is simple and works across browsers:

document.getElementById("myButton").onclick = function() {
    alert("My button has been clicked");
};

When a second listeners is bound to the same event on this element, it will however override the first one.

document.getElementById("myButton").onclick = function() {
    alert("Only this alert will now be displayed");
};

Clean event listeners

Current Web browsers offer a clean way to add event listeners to an element without overriding the previous ones. Using a JavaScript library such as jQuery is especially useful in this case since their are two different ways to do so, one specific to Internet Explorer and one defined by the w3c otherwise and adopted by every other browser vendor[1. attachEvent in Internet Explorer and addEventListener]. jQuery offers an unified way to deal with those two different implementations:

jQuery("#myButton").click( function(event) {
    alert("My button has been clicked");
});
// And later...
jQuery("#myButton").click( function(event) {
    alert("And this alert will also be displayed");
});

Event bubbling

Another useful characteristic of events in Web pages is that most of them bubble in the DOM: once an event occurs on an element, it will also occur on its direct ancestor, then its ancestor’s ancestor until it hits the document root or an event listener prevents it to bubble. For example, with the following unordered list and script:

<ul id="myUnorderedList">
    <li class="blue">A first <i>list item</i>.</li>
    <li class="red">A second <i>list item</i>.</li>
</ul>
jQuery("#myUnorderedList").click( function(event) {
    alert("The list has been clicked");
});

No matter where the user clicks in the list, being on a list-item, an element nested in a list-item or in the gap between two list-items, the click event will still be detected by the listener set at the list level (on the <ul> tag). The event parameter that is passed to the function bound to the item carries information about the exact place where the click event occurred in its target property:

jQuery("#myUnorderedList").click( function(event) {
    alert("You have exactly clicked a " + event.target.nodeName + " element.");
    // event.target.nodeName will be I, LI or UL depending where the cursor was.
});

This is especially useful to avoid adding an event listener for each item of the list.

Event delegation

Using the target attribute, it is also possible to know in which particular <li> did the click occurred, even if the click occurred on an element nested in the <li>:

jQuery("#myUnorderedList").click( function(event) {
     var target = event.target;
     // If the element clicked was nested in the li,
     // it is necessary to loop through its ancestors
     // until a li is found.
     // The second test ends the loop when no li is found.
     while(target.nodeName != "LI" && target.ownerDocument)
         target = target.parentNode;
     // If a li has actually been found...
     if(target.nodeName == "LI")
         alert("The colour of this li is " + target.className);
         // target.className will be either "red" or "blue"
});

Another advantage of event delegation, beside requiring to add an event listener only once, is that its logic will still work for any item appended later to the list. In dynamic web pages where additional content can be loaded arbitrary (by an ajax request for example), this proves to be an invaluable mechanism.

jQuery1.3 helpers

The 1.3 version of jQuery introduce two helpers which make event delegation a breeze:

the .closest( selector ) function

This function is an equivalent to the loop that has been written in the previous code snippet to look for a specific ancestor of an event target. The equivalent of the above code with the .closest() is as short as:

jQuery("#myUnorderedList").click( function(event) {
     var $target = $(event.target).closest("li");
     // if a li has actually been found
     if($target.length)
         alert("The colour of this li is " + $target.attr("class"));
});

The function can take any type of CSS selector as argument, in a pure jQuery fashion:

jQuery("#myUnorderedList").click( function(event) {
     var $target = $(event.target).closest("li.blue");
     if($target.length)
         alert("The colour of this li is blue");
});

The upcoming jQuery1.3.3 adds a second optional argument to closest, the context. Previously, when an element clicked was not nested in an element matching the selector, every ancestor of the target where still tested up to the root of the page. It is now possible to end the search for a target ancestor when a given element is hit. For example, in the previous snippet of code, there is no need to search for a list-item in the unordered list’s ancestors. In most case, this will be as simple as using the context of the event listener itself:

jQuery("#myUnorderedList").click( function(event) {
     var $target = $(event.target).closest("li.blue", this);
     if($target.length)
         alert("The colour of this li is blue");
});

the .live() function

This function has to be used just after a DOM query to filter events occurring on the matched set of elements, even if other elements matching the selector are added later to the document.

jQuery("li.blue").live().click( function(event) {
      alert("The colour of this li is blue");
});

Although this might seem like a magic and somewhat obscure way of achieving event delegation, the underlying principle is actually exactly the same as the one used in the previous code snippet. Once again, it is possible to improve the performance of this function by providing a context to the selector. In this case the context of the jQuery object is used:

jQuery("#myUnorderedList").find("li.blue")
  .live("click", function(event){ ... } );
// or
jQuery("li.blue", jQuery("#myUnorderedList"))
  .live("click" function(event){ ... } );

It is important to note that both .closest() and .live() will only be useful for events which actually bubble in the DOM. Events such as focus, blur, mouseenter and mouseleave thus cannot be used with .live().

Dealing with mouseover/mouseout instead of mouseenter/mouseleave

mouseenter and mouseleave are events originally specific to Internet Explorer (but available in all browsers using jQuery) which do not bubble. This specificity is very useful to prevent listeners from being triggered by events happening inside nested elements. With the following list:

<ul id="myUnorderedList">
    <li>A first <i>item</i>.<em class="tips">Hidden info</em></li>
    <li>A second <i>item</i>.<em class="tips">Hidden info</em></li>
</ul>

Trying to display the hidden information only when the cursor is over a list-item could be written as follows:

$("li").mouseover( function() {
    $(this).find(".hidden").show();
}).mouseout( function() {
    $(this).find(".hidden").hide();
});

With such code, the hidden info would flickr every time the cursor is moved from or to the text wrapped in a <i>, because a mouseout event occurs even when the cursor is moved to a children of the previous element. Using mouseenter and mouseleave events effectively solves this problem. However this advantage makes event delegation impossible at the same time. The issue can actually be solved by combining the use of .live() on the mouseover and mouseout events with .closest() to filter out events for which the origin of the cursor is another element in the same <li>, using the relatedTarget attribute of the event:

$("li").live("mouseover", function(event) {
    var $related = $(event.relatedTarget).closest("li");
    if(!$related.length || $related[0] != this)
        $(this).find(".hidden").show();
});
$("li").live("mouseout", function(event) {
    var $related = $(event.relatedTarget).closest("li");
    if(!$related.length || $related[0] != this)
        $(this).find(".hidden").hide();
});

Using event delegation with mouseover and mouseout however has a non-negligible impact on performance, since a significant amount of code is run every time the cursor enters a nested element, just to check if the bound function should be executed. This issue and a possible improvement of jQuery’s code are detailed in a thread in jQuery’s Google group.

Conclusion

The helpers added in jQuery 1.3 make it really easy to implement event delegation and understanding how they work allows for more advanced problems to be easily tackled. As a general rule, it can be considered that an optimisation is always possible using event delegation wherever the same event listener is used for two different elements. An event listener should be bound only once, using event delegation if necessary. Using it with mouseover and mouseout should however be done carefully.

It is also recommended to read the documentation page of .live() to understand the limitations of this function. One might also want to know how to .unbind() events (.die() being the equivalent when using .live()).

Server-side JavaScript and working with ActiveJs

August 1st, 2009

In my effort to make it easy to contribute to ToDoSo, I have chosen JavaScript as the server side technology for this project.

Although Ruby on Rails is the technology of choice for most Web applications that appeared lately on the Internet 1, it requires to learn not only HTML, CSS and JavaScript for the client side development but an additional technology for the server side development (a new language and a complete Framework in the case of Ruby on Rails).

Some would argue that Ruby is a really simple and rather self explaining language, that Ruby on Rails is a mature framework and altogether they make Web development a breeze once you know how to use it. I agree, but I also know that JavaScript is a great language as well and that it would lower the technological barrier if it was possible to use it on the server side with a framework comparable to Ruby on Rails.

There are already a large number of server-side JavaScript interpreter listed on wikipedia and on the ServerJs project page of Mozilla. There is also Jaxer, developed recently by Aptana. I recommend to watch the introductory videos on aptana.tv to have a brief overview of what is possible with it, but in brief its main features are:

  • the possibility to access and modify the DOM on the server before it is sent to the client (you can even use the canvas API to dynamically create images)
  • the possibility to share code between the client and the server sides (you only have to write your form validation logic once)
  • the possibility to call server side function from the client side (using invisible ajax requests)

Most of those server-side interpreters are based on open-source JavaScript interpreters that are to be found in modern web browsers 2 which means that they benefit from the same speed improvements that we saw recently in Web browsers.

There are also few JavaScript MVC frameworks similar (at least in the spirit) to Ruby on Rails built on top of this server technologies: the most advanced ones seem to be Helma NG and ActiveJS. Both projects however, still seem to be in an early stage of development. Once again it could take ages to make a deep comparison of those and it wouldn’t help to get ToDoSo real. Instead you’d rather choose one and stick with it for better or for worse.

I’ve chosen ActiveJS because it is built originally for Jaxer and thus doesn’t require any configuration to get started if you are developing with Aptana Studio. Moreover, the ORM layer of ActiveJS (ActiveRecordJS) offers an abstraction not only to MySQL and SQLite databases (on the server side) but also to client-side persistence such as Google Gears or the SQLite database that is to be found in Safari and the iPhone Web browsers. Its route component is similar to the Ruby on Rail’s one but also offers deep linking on the client side, in the Jaxer spirit.

Hacking into ActiveJS

Because ActiveJS is still young, it is really likely to miss some features that might be important for your project and the best solution will be to hack into it instead of waiting for someone else to do the job. So here is how to configure a development environment to be able to build ActiveJS from sources (as a reminder for myself):

  1. I assume you are developing with Aptana Studio and you have the Jaxer and Git plugins installed.
  2. Fork the ActiveJS repository on Github.
  3. Import it as a project in Aptana (File > Import > Git Repository, choose git+ssh as the protocol and don’t change the username)
  4. Ruby needs to be installed in its 1.8 version because the build script depends on ftools, which is deprecated in ruby1.9. With Ubuntu and probably other linux distribution, the ruby-dev package is required as well.
  5. The package rubygem is then required to install most dependencies of the build script: json, packr (beware, this might soon be replaced by YUI) and rdiscount. In any case look at the beginning of build.rb to find the dependencies of the script.
    $ sudo gem install rdiscount 
  6. Remember to configure your editor to use 4 spaces instead of tabs and try to respect the coding style.

Et voilà! You’re ready to change the files in the src folder, build active.js, test your modifications and send pull requests to the original branch.

$ ruby1.8 ./build.rb compress

My first tasks will be to improve the relationship features because it doesn’t behave as a proper ORM layer currently and to add support of HTML5 elements to the view component.

  1. twitter – most job offers require to be familiar with this framework -, github, uservoice, zendesk, lighthouseapp – all of them using the Ruby on Rails cloud engineyard – and getsatisfaction – created by rubyredlabs – to name a few
  2. SpiderMonkey and V8 mainly, I haven’t heard about any based on SquirrelFish or TraceMonkey so far but it seems that Jaxer will switch to the latter

Getting ToDoSo Real!

July 24th, 2009

I’ve finally been reading Getting Real: a great book by the guys behind Ruby on Rail, about the method to get a Web application real: online,  engaging and ready to use as soon as possible. It changed my plans for the work to come on ToDoSo without any doubt.

There are only five weeks left until the hand-in date of the project’s report, and what has been achieved so far? I’ve written quite a good specification of the project with a detailed analyze of the accessibility issues in presentations, I’ve dived deep into the mess that vector graphics are on the Web… But I’ve been creating mockups for less than one month and the first prototype is not even one week old. What exciting part of the application have I to show? Well, I’m proud of this first mobile prototype but it’s a bit far from the core of a presentation software.

I was intending to write about the rational behind the interface concepts and stuff… Yes, I could spend hours talking about why I’ve chosen the Open Web, Github, jQuery, Jaxer,  just like I wrote 2000 words to compare dojo.gfx to Raphaleljs. Eventually I would event gain enough knowledge in some of those technologies to conclude that they are not good enough and start my own project. But this is pointless, it is a waste of time, effort and creativity. This is not helping to get ToDoSo real, to let people get as excited by it as I am. Worse, it’s even undermining my enthusiasm to have to write about that when I could be creating svg mockups or coding some prototypes with my weapon of choice. Focusing on the details, thinking about all the insignificant features of v2.0 and considering performance problems early on is definitely things that I’ve done wrong.

I’m instead going to put all of my efforts into getting real, starting yesterday : ) I’m going to write stories about ToDoSo: why people would use it and which feature they could expect from it. I’ll also create the mockups of the authoring part of the application (and strip the shiny vector graphics and animation feature out) and create the most important prototypes: the player, the authoring part and the management interface (maybe in a different order). I’ve already updated the homepage of the project to add a small description and separated the content into tabs.  I’ve opened a Launchpad for the project and I’m going to twitt more regularly about it.

I’m anyway pleased to have the confirmation that there are parts of this project that I’ve been doing right: starting with the interface, epicenter design, using real words (the “Cat guide to world dominashun”)… and choosing the name of the app (definitely better than SlideMe ; )

Whoever you are, you, visitor of this blog, please do not hesitate to be the first one to file a bug in launchpad, or to ask a question there!