Saturday, August 31, 2013

Wonky UI behavior when including multiple jQuery libraries

We use blockUI in our web application to prohibit user interaction in a couple scenarios, particularly when making ajax calls.  There was strange behavior where whenever the blockUI was invoked, it didn't block the UI until the ajax call returned!

Here's what I did in my investigation to find out why:

  • Just to confirm the blockUI library worked, I created a simple webapp example, where I only included the latest blockUI library and latest jQuery libary.  Calling blockUI directly prior to the ajax call, and then unblockUI after; everything worked great.  
  • After that was confirmed, brought this simple example into the actual web application, things went wonky.  The actual web application has all sorts of jQuery libraries (jQuery base, jQuery tools, jQuery ui, etc), so something with the javascript libraries was causing an issue.
  • I thought perhaps the specific attributes of the jQuery.ajax calls weren't proper (i.e. asynch was false when it should have been true).  Confirmed this was not the case when bringing the same ajax call in a simple JSP file in the actual web application.
  • Did a search in the code base and found not one, not two, but THREE versions of jQuery base library in the system!  Three files were named jQuery.js, jQuery1.8.0.js, and jQuery1.9.1.js.  And on top of that, the jQuery tools library had jQuery 1.4.2 embedded inside of it!)
  • Created a breakpoint in the browser developer tool, watched $.fn.jQuery; and saw that indeed we were using jQuery 1.4.2 library.  This confirmed that the jQuery library embedded in the jQuery tools library was "The Winner" (not any of those other THREE jQuery libraries in the code base!)
  • Just to confirm the blockUI library worked with jQuery 1.4.2, I commented out references to those aforementioned THREE libraries.  I reverted back to an older version of blockUI (2.42) that only needed jQuery 1.2.3 or later.  Calling blockUI directly prior to the ajax call, and then unblockUI after; everything worked great.

Conclusions from this case study?

  • Using jQuery 1.4.2, and blockUI 2.42 worked fine!  Since jQuery was included multiple times in the code base, weird behavior occurred (even though you would think the latest js include would "override" the ones included above it - NOT TRUE)
  • Calling blockUI can be configured with fadeIn of 0 (as to not delay the blockUI overlay from being displayed)
  • The jQuery ajax must be asynchronous (synchronous will freeze the browser).  This is discussed in this stackoverflow article.
  • Do not include multiple versions (or even the same version multiple times) of jQuery javascript library or you will eventually get strange behavior

The key ideas I gathered from this is a common problem:

  • There are all sorts of problems that occur when there are conflicting dependencies in libraries that are used (jQuery, java, etc).
    • Developers chasing phantom bugs
    • De-stabilitzation of the application
    • etc.
  • Every "once in awhile", you need to do an analysis of what libraries (UI or backend) and dependencies have been introduced to the system.  Or as new libraries become available, you may also need to do this analysis to determine if you want to upgrade or not

TODO: I plan to look into requireJS for jQuery, which is a javascript library and module loader that only loads js files as needed.

No comments:

Post a Comment

I appreciate your time in leaving a comment!