A Few JavaScript/jQuery Best Practices

jquery-bestpractices

I recently completed a pretty good size HTML5, JavaScript, SharePoint 2010 application for mobile devices. I got the opportunity to use some fairly young technologies so had to dig or in some cases determine my own best practices. Here’s where I ended up after the dust settled.

1. Use Frameworks

Choose your poison but there no reason you need to suffer through writing plain old JavaScript. There are a ton of great frameworks out there each with their own pros and cons. With the growing number of devices and browsers out there you want to make sure that someone else is doing your compatibility testing and frameworks offer that additional benefit. Here are a few that you should probably be aware of:

jQuery – Has a strong following with a great plugin system. Very easy to extend. My preferred framework all around but the  mobile API is still in beta but showing some real promise. Seems like the best pick for SharePoint work and/or public facing website in general. The best part about jQuery is that you still write HTML, CSS, JavaScript the way that you are used to… but you just do it much faster.

Ext – Just recently started working with this framework for mobile applications. This is probably going to become my framework of choice for building rich  mobile and web applications. The thing about Ext is that the application is written entirely in JavaScript… and this can making the learning curve a bit steeper.

Prototype and Dojo – Not going to comment on these as I haven’t used them enough to compare but they are pretty well known with a strong following.

2. Use $.ajax instead of the shorthand $.getJSON

While the short hand $.getJSON is great it has 1 BIG fault that makes it a deal breaker for me. Caching. Chrome and Firefox correctly (as usual) handle all JSON requests as non-cachable but IE will return a 304 (NOT MODIFIED) and simply pull your JSON results right out of the browser cache. This makes for a very frustrating troubleshooting process when you perform and action and then refresh the server side state to find out that while the server is up to date… the client is not.

Instead, always use the longer $.ajax function as follows (note the cache setting):

$.ajax({
url: '/url/to/json/request',
dataType: 'json',
cache: false,
data: { field1: 'value1', field2: 'value2' },
success: function (response) { // do something with the result }
});

This will append a timestamp to the query so it will look something like this /url/to/json/request?_=131588349217 and thus ensuring that even if caching does occur the next request will not result in a 304.

3. Use Closures

In .NET code we always ensure that we sign our solution when necessary, properly namespace our files and our DLL to ensure maintainability and avoid name conflicts. But when it comes to JavaScript we just slap something together and make it work.

// namespace definition
var ns = {};
 
// closure(function (ns) {
   ns.helloWorld = function() {
      alert('hello world');
   };
 
   ns.helloWorld2 = function() {
      alert('hello world2');
   };
})(ns);
 
// usage
ns.helloWorld();

View the jsfiddle
The idea here is that we declare a single namespace variable and then pass that variable into our self executing function and add additional methods and variables. This is especially important with jQuery as other frameworks have started using the $ variable. What does this look like?

(function($) {        
    // code goes here that can safely use the $
})(jQuery);

In this case we pass in the existing variable “jQuery” which is not going to conflict with another framework and then within our function we call that variable $ so that we can use jQuery with the short dollar sign alias.

4. Pick a Design Pattern

Historically JavaScript has been treated as a third rate citizen when it comes to programming languages… providing small snippets of quick fixes or enhanced functionality. We’ve dropped script tags anywhere we could just to fix a problem, within web parts, in the masterpage, in a page layout, anywhere to solve a problem. Hopefully that day is coming to an end as rich internet applications have become the norm people are expecting asynchronous postbacks.

What I’ve been struggling with is how to merge the design patterns into a world of ASP.NET and SharePoint and here is where I’ve landed for now.

SharePoint – General Best Practice

If you’re enhancing a web part or doing some kind of page enhancement then you should probably be building a jQuery plugin to ensure that your code is namespaced and properly encapsulated within a JavaScript closure.  There are plenty of guides out there on how to build a jQuery plugin so I’m not going to repeat that content.

SharePoint – Ways to Add your JavaScript

Location Considerations
Masterpage Add your javascript to the masterpage when it affects all pages or has a very small footprint. Good examples include: Script that runs on all pages such as navigation/flyout helpers or small plugins that can be reused throughout a site. This is a common decision for internet facing SharePoint sites. Either include the JavaScript in the head tag or right before the closing body tag.
Page Layout If you have a special page layout such as one that displays a Bing map control based on an address in the page metadata then adding the JavaScript reference into the page layout is a perfect options. By using the PlaceHolderAdditionalPageHead you can embed those resources files into the head tag of the page.
Delegate Another great way to get JavaScript resources into a page is through feature activation. This way you can include your custom script files immediately when your web part feature is activated. You just need the following XML in your feature file:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Control 
    Id="AdditionalPageHead"
    Sequence="500" 
    ControlSrc="~/_ControlTemplates/Namespace/UserControl.ascx" />
</Elements>
Content Editor Web Part Great for a single page… especially for one off solutions like enhancing calculated columns.
Custom Web Part Within your visual web part CreateChildControls method you can do something like this:

Page.ClientScript.RegisterClientScriptInclude(
"jquery", 
"/_layouts/Namespace.Goes.Here/jquery-1.6.1.min.js");
I'm a public speaker and the Chief SharePoint Architect for Eastridge, a Microsoft Gold Partner specializing in SharePoint and custom application development in Winston-Salem, NC. I focus on the SharePoint platform with a specialty in Information Architecture, Publishing and Best Practices.

Got something to say? Go for it!