Javascript FTW

Open Source

So You’re a Web Developer?

TITLE_IMAGE

That’s pretty cool. And if you’re here wanting to develop mobile apps, that’s pretty cool too. We have an unparalleled HTML5 app platform which makes it very accessible for those familiar with building web apps to transition into making mobile apps. But is it ever that easy?

On the web, we’re accustomed to building page-to-page or AJAX navigation, as opposed to using templates and transitioning from view-to-view all within JavaScript; it’s a nice top-down/linear way of thinking. We start at the top with a request, scripts execute, and then the page is done. However, we want our apps to feel like apps – not like webpages.

So, we use all sorts of magical libraries and frameworks to do the legwork for us. We slap their scripts in the “head” tag, create some views, create either a server-side or client-side model, and then we have ourselves an app. But then it’s slow. Or it’s buggy. We try to fix it and the framework or library we’re using is picky, or requires more modification than what’s really worthwhile. We want to make changes (we know your boss asked for it) and suddenly we have to re-write our code. But what really happens is you hack something together that merges your codebase into one hot unmanageable mess. Next thing you know, the HTML5 app you’re building isn’t awesome. We want awesome. So let’s fix that.

Where Do We Start?

Before you can worry about writing efficient JavaScript, you need to write efficient JavaScript. Yeah, you read that right. If your codebase isn’t scalable or manageable, there’s no point in writing sneaky algorithms. In order to squeeze every bit of performance out of your app, you need to be able to see how your codebase talks to all of its different parts. If you don’t, you’re gonna have a bad time. Not only will this help you see your code more clearly, but it will help the JavaScript engine that runs your script see your code more clearly (and therefore, run your code faster). We will talk about that more in my next blog post, but for now, trust me!

You want to make each piece of code you write as modular as possible. Begin by thinking of your app as being made up of smaller programs. Just like you would group methods and properties together to make a class based on their function, group your classes together based on the tasks you need to perform. I like to call these wee programs “modules” – for the obvious reason that they keep your code modular. The only top-down/linear part of your script we want is the starting of these modules. From there, you should be able to start, stop, add, or remove them. Now you’re almost ready to write some awesome JavaScript. Below are some initial tips; we’ll get started with these, and then next time we’ll delve into other speed boosting and architecture tips.

Your code should:

  1. Have a namespace/package. Organize all of your classes in a logical manner. This will enable you to have a large collection of classes without interfering with the names of other classes you have written or have included in your app.
    // EXAMPLE: Create our namespace
    	if (!window.com)
    		com = new Object();
    	if (!com.grahamzibar)
    		com.grahamzibar = new Object();
    	if (!com.grahamzibar.mouse_tracker)
    		com.grahamzibar.mouse_tracker = new Object();
  2. Be able to run more than once. If your code breaks when it is called multiple times, you’re gonna have a bad time. This goes for everything: classes, methods, scripts, etc. You need to take into consideration that you’re code might run synchronously or asynchronously throughout the lifetime of your app and, as a consequence, may be invoked from two or more separate places from within your app in a very short interval of time. Below, we have a view that can be applied to any two DOM Elements and can be instantiated any number of times.
    // EXAMPLE:	
    	mouse_tracker.View = function View(renderContainer, bodyContainer) {
    		var MAX_VALUE = 255;
    		var MIN_VALUE = 225;
    
    		this.displayCoordinates = function(x, y) {
    			// Incremental string concatenation(sp?) is the bomb.  Trust.
    			var result = 'x: ';
    			result += x;
    			result += 'px - y: ';
    			result += y;
    			result += 'px';
    			renderContainer.innerHTML = result;
    		};
    
    		this.modifyBackground = function(x) {
    			var half_width = bodyContainer.offsetWidth / 2;
    			var val = Math.round((Math.abs(x - half_width) / half_width) *
    					(MIN_VALUE - MAX_VALUE) + MAX_VALUE);
    			var rgb = 'rgb(';
    			rgb += val;
    			rgb += ', ';
    			rgb += val;
    			rgb += ', ';
    			rgb += val;
    			rgb += ')';
    			bodyContainer.style.backgroundColor = rgb;
    		};
    
    		this.clear = function() {
    			renderContainer.innerHTML = '';
    		};
    	};
  3. Usually be an instance of some class. If it isn’t, you’re probably breaking rule 2. Break rule 2, and you’re gonna have a bad time.
  • Inherit, inherit, inherit. A view in your app should be some class (let’s call it app.pages.SettingsPage) which inherits some base view class (maybe app.pages.BasePage). This, in turn, probably inherits some event dispatcher (perhaps events.EventDispatcher) so another class can use it to display page request and load progress by adding event listeners. This is a great way to help keep your code DRY (http://en.wikipedia.org/wiki/Don’t_repeat_yourself).
  • Disposable. When you create an object and it does all sorts of things like add timers and subscribes to events, always write the reverse so you can clean-up when needed. You never know when this will come in handy and will save you hours of headaches and frustration. This will help you keep on top of removing event listeners and references to objects that are no longer required to avoid memory leaks and buggy code.
    // EXAMPLE:
    	mouse_tracker.Controller = function Controller(model, view) {
    		var onChangeModel = function(e) {
    			view.displayCoordinates(e.x, e.y);
    			view.modifyBackground(e.x);
    		};
    
    		var init = function() {
    			model.onchange = onChangeModel;
    		};
    
    		this.dispose = function() {
    			model.onchange = null;
    		};
    
    		init();
    	};

Let’s use the above concepts together in a quick code sample. The only item in the above list I didn’t get the chance to use was inheritance. It’s a bit beyond the scope of the code sample this time around, but I’ll certainly touch on that next time when we talk about events.

I have a very particular way I like to write my JavaScript that tends to boggle developers from time-to-time (note the way I write classes). Therefore, feel free to ask questions in the comments below and I’ll be sure to respond as best I can.

Later, mobile devs.

About grahamzibar

A young programmer from Toronto that loves Web Standards, good JavaScript, and long walks on the beach. For real.

Join the conversation

Show comments Hide comments
+ -
blog comments powered by Disqus