Monday, 13 February 2012

Streaming JavaScript is still Great! Use It!

So back in January 2009 I was advocating splitting your codebase up into different functions, where you can stream in different logic bit by bit as required. This was due to support explosion of smart phones which didn't have the bandwidth or processing power desktop computers had.

It's been over 3 years since supporting this pattern, and I've honestly had very little to complain about, but I figured I'd highlight two of the negatives I've come across over the years.
  • Caching - Anything you stream will not be cached, so you'll have to cache the JavaScript yourself.
  • Bugs - As this isn't a practiced design pattern in the world of web programming, browser vendors don't always check for it before pushing out an update.

Caching
This one's a piece of cake. Simply use LocalStorage to store your cached JavaScript file.
LocalStorage gives you around 2mb no questions asked storage to store binary data, which is more than enough to store small javascript files.

Here we walkthrough the process of caching a JavaScript file.

 var jsScriptData = false;  
   
 // If we have localStorage  
 if( window.localStorage )  
 {  
   // See if we have the data  
      if( window.localStorage.getItem( "jsData" ) )  
      {  
           jsScriptData = window.localStorage.getItem( "jsData" );  
      }  
   else  
   {  
     // If not download the file normally  
     jsScriptData = DownloadFile( "http://urlto.com/streamingFile.js" );  
       
     // Then save to localStorage  
     window.localStorage["jsData"] = jsScriptData;  
   }  
 }  
 else  
 {  
   // If we don't have localStorage download the file normally  
   jsScriptData = DownloadFile( "http://urlto.com/streamingFile.js" );  
 }  
   
 // Create a new script element  
 var newScript = document.createElement( 'script' );  
   
 // Fill in the script element with more source code  
 newScript.text = jsScriptData;  
   
 // Add our script to the document  
 document.body.appendChild( newScript );  

Of course more smarter checks can be put in, for example, checking for an update every week, or having a flag in the main JavaScript file to flag when to stream in the update.


Bugs
Next issue to discuss is bugs. As of writing Mozilla recently updated Firefox to 10.0.1, which is great, updates are always good. However, for some reason iGrapher.com stopped working on the OSX skew.

On Windows it was fine, but the OSX just hung on streaming in more JavaScript files. Now on the iGrapher project we load 4 files.
  • startup - 21kb file which loads in the main view UI and downloading engine.
  • main - 98kb file which handles the graphing and stock market downloading logic.
  • extras - 150kb file which ads additional tools and menus to the graphing component.
  • news - 33kb file which handles the news stories.
What's shown in the screenshot above is the webapp hung getting the extras file. Now I didn't put in any time to debug the issue as I'm more focusing on the updated codebase. So unfortunately I can't deduce what exactly in the code causes it, but I found that by combining the startup and main files together into one file. The extras and news files stream in fine.

Mysterious, but I thought it'd be useful to highlight that yes, bugs occur, when they perhaps shouldn't.


Conclusion

I come across bloated websites all the time which rely on the browser to load in lots JavaScript files at the same time. This delivers a poor and very staggered start up experience. It's poor on desktop computers let alone the exploding smartphone/tablet market. We think about streaming in content all the time, why stop there? Let's start thinking about streaming in processing and fix this poor user experience we've accepted as the norm.