Behavior, Content, Money – 3 Things you should never give away for free!!!

BCmoney MobileTV

HTML5 WebWorker and Local Storage to improve long-running tasks and slow AJAX

Posted by bcmoney on March 16, 2014 in AJAX, HTML with No Comments


No Gravatar
English: Diagram of the HTML5 block elements: ...

English: Diagram of the HTML5 block elements: body, header, navigation, section, article, paragraph, aside, and footer. (Photo credit: Wikipedia)

So there’s tons of hype around HTML5 which kicked off in a big way in 2010, and is still riding strong. Sure enough, everyone is raving about the shiny new multimedia features with HTML5 video & HTML5 audio, as well as the UI/UX features and capabilities such as Drag & Drop file uploads, interactive graphics via SVG & HTML5 Canvas, or the visual effects made possible by CSS3 such as animations and transitions. Mobile web usability enjoys a well-deserved close following with discussions on supporting Swipes, Pinches, Gestures, etc on top of the basic Keyboard & Mouse actions. Even data-centric stuff typically the realm of geeks only such as Semantic Layout block elements (as depicted on the right) or Microdata’s new “data-” attribute that allows extending any element as needed with additional metadata, making possible the initial promise of Microformats.

Yeah, all that stuff is pretty cool, I’ll admit. I’ve covered them in the past and will continue to do so. But what about some of the less exciting, more basic performance-related improvements such as WebWorker and localStorage? I think those deserve just as much time in the spotlight because they offer some serious benefits to developers and users alike, so I’ll talk a bit about them here.

 

WebWorker

HTML5 WebWorker allows long-running tasks to run the background while the application can simply notify the user that work is being done and allow them to carry on with other activities. Good candidates for WebWorkers are tasks such as AJAX queries with expensive database operations (like several joins across tables, or, lookups on data types that can’t reasonably be indexed for some reason), or, processor-heavy computations on the back-end such as statistical machine learning jobs or big data cross-analysis that need to be ran before a proper response can be returned.

Those are the obvious use cases, but its also a good candidate for simple performance improvements such as bulk data lookups or batching up multiple transactions at once. There’s not too much to the JavaScript within a WebWorker itself, take my basic example in a file “webWorker.js”:

//listen for incoming messages
self.onmessage = (function(evt) {
  console.log('Called to WebWorker with: ' + evt.data);
});

//execute some kind of a long-running task
console.log('Calling from WebWorker with: ' + content);
self.postMessage(content);

//close after the single long-running processes completes
self.close();

Let’s say you wanted to also include an external JavaScript file to use some common library type functions. No problem, but you must avoid use of window and document since WebWorkers don’t have access to these objects due to limitations by design that prevent the WebWorkers from monkeying around with the actual client directly. What that means is you can’t simply add jQuery since it relies heavily on these. To import/include a JavaScript library or file that meets these criteria, just use:
importScripts('MyLibrary.js');

The code required to call this is equally simple and in my simple use case I just have it setup inline:

  function slowWebWorker() {
    //check that DedicatedWorkers are supported, if so use them
	if (typeof(Worker) !== 'undefined') {
		var webWorker = new Worker('webWorker.js');
		//WebWorker driven AJAX
		webWorker.onmessage = (function(evt){
			processMsg('msg', 'Msg from WebWorker: 
' + evt.data);
		});
	} else {
		alert('WebWorkers not supported in this browser, use regular AJAX');
	}
  }

I’ve put together the simplest possible “side-by-side” demo I could think of that still gets the point across. It shows a simulated long-running AJAX request and how it could be improved, maintaining the user’s control of the application rather than blocking them from doing anything until the long-running process is completed. Checkout below:


-or-

To test out the demo, hit the AJAX button first and notice how control of the application/page has been lost (if you click around too much while this long-running process is in progress, you can crash that tab or even the whole browser). Next, hit the Web Worker button and notice that you can continue along your way, filling out form data or opening dynamic browser input types. Also note, this is a bit of an easter egg but I’ve listed all the main new HTML5 Form input fields so you can check out how those render on various browsers. The degree of variation between browsers on these new HTML5 fields really harkens back to the early days of JavaScript/VBscript and DHTML/CSS differing implementations for behavior and design of a page.

 

localStorage

Once you’ve got a hold of some “expensively computed” data like the type you’d need to run through an HTML5 WebWorker, what should you do with it? Toss it away for each page refresh or accidental browser tab closure only to need to make the expensive request again? I don’t think so! Especially if that data is not likely to need to be updated (or become out of date between client/server) very often. Why not hold on to that data for a while on the client side, and only refresh it when we know for sure it needs an update, or, send it back to the server when we’ve made significant changes to it. Even in cases where its not that important whether or not the data on the client and server are slightly out of date, its probably a good idea to hold on to it for a while. Well in the past we used these little 4kb files called Cookies to store data on the client.

In the words of DiveIntoHTML5:

  • Cookies are included with every HTTP request, thereby slowing down your web application by needlessly transmitting the same data over and over.
  • Cookies are included with every HTTP request, thereby sending data unencrypted over the internet (unless your entire web application is served over SSL)

So noteworthy performance gains (and arguably better privacy/security) stand to be realized by using anything other than Cookies where possible. Initially some browser and plugin vendors came up with their own solutions (Google/Chrome with Gears, Microsoft/IE with ActiveX, Mozilla/FF toyed with SQLlite, Opera with Widget preference metadata, Adobe/Flash with FlashCookies, etc).

 


-or-

To test this demo, you should be able to use any of the Create, Read, Update & Delete (CRUD) buttons under the localStorage section or sessionStorage section. When doing so, you can compare the code and capabilities to this simple Cookie storage example based on my initial Cookie handling code I threw together back in the day for the BCmoney.JS framework I attempted to put together to “rival jQuery” hah yeah right, but it was fun and came in handy multiple times as the code were the most common tasks I had to do on freelance web projects.

 

References

  1. Mozilla – Using Web Workers: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers
  2. HTML5 Web Workers (REFCARDZ): https://dzone.com/refcardz/html5-web-workers
  3. HTML5 rocks – The Basics of Web Workers: https://www.html5rocks.com/en/tutorials/workers/basics/
  4. HTML WebWorker & jQuery AJAX call: https://stackoverflow.com/questions/4838883/html-web-worker-and-jquery-ajax-call
  5. HTML5 WebWorkers & AJAX: http://www.tcsc.com/html5-web-workers-and-ajax/
  6. HTML5 WebWorker demo: https://html5demos.com/worker/ | Similar example without WebWorkers: https://html5demos.com/non-worker/ (WARNING: will hang your browser)
  7. Mozilla – Web Storage APIs: https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API
  8. Saving Data with localStorage: https://hacks.mozilla.org/2009/06/localstorage/
  9. HTML5 Storage: https://html5demos.com/storage/
  10. HTML5 Storage events: https://html5demos.com/storage-events/
  11. HTML5 localStorage .vs. sessionStorage: http://tutorials.jenkov.com/html5/local-storage.html
  12. Storing Objects in HTML5 localStorage: https://stackoverflow.com/questions/2010892/storing-objects-in-html5-localstorage
  13. What is the max size of localStorage?: https://stackoverflow.com/questions/2989284/what-is-the-max-size-of-localstorage-values
  14. What is the difference between localStorage, sessionStorage, session and cookies?: https://stackoverflow.com/questions/19867599/what-is-the-difference-between-localstorage-sessionstorage-session-and-cookies
  15. Local Storage .vs. Cookies: https://stackoverflow.com/questions/3220660/local-storage-vs-cookies/3220802#3220802
Leave a Reply

No trackbacks yet.

No post with similar tags yet.

Posts in similar categories

BC$ = Behavior, Content, Money

The goal of the BC$ project is to raise awareness and make changes with respect to the three pillars of information freedom - Behavior (pursuit of interests and passions), Content (sharing/exchanging ideas in various formats), Money (fairness and accessibility) - bringing to light the fact that:

1. We regularly hand over our browser histories, search histories and daily online activities to companies that want our money, or, to benefit from our use of their services with lucrative ad deals or sales of personal information.

2. We create and/or consume interesting content on their services, but we aren't adequately rewarded for our creative efforts or loyalty.

3. We pay money to be connected online (and possibly also over mobile), yet we lose both time and money by allowing companies to market to us with unsolicited advertisements, irrelevant product offers and unfairly structured service pricing plans.

  • Archives