Our Journey in Optimizing and Bundling JavaScript for Web Applications

When building a web application, optimizing the loading process is important.

Previously, we used Uglify-ES and recently Terser to minify individual JavaScript files to help reduce the packages and load time.

With the next release of iPhora Automatic coming very soon, we wanted to significantly reduce the loading time needed and the number of HTTP requests handled by the Domino server.

Our struggles for the past few weeks have been figuring out the right JavaScript bundler that works with our Dojo Toolkit-based framework.

So why are we still using Dojo Toolkit you might first ask? Many have moved away from Dojo Toolkit, the granddaddy of JavaScript frameworks. Dojo provides us the core widget inheritance framework that is not just used for creating widgets like fields and combo boxes, but is used for building the many different app layers of iPhora not just statically but dynamically in real-time. It allows us to have a secure and fast SPA (single page application) architecture. We don't use any of the original Dojo widgets (Dijits). Each widget that appears in the UI is a custom widget object that is built specifically to work within our framework. 

We first looked at Webpack which is probably the most popular JavaScript and resource bundler. IBM/HCL created the dojo-webpack plugin to bundle and minify Dojo Toolkit based applications and is still in use. We got dojo-webpack working with the latest version of Webpack, v5.98 and Dojo 1.17.3.  But we had to upgrade to Node 18.20.8 and NPM 9.3.1. This reduced the loading time from 4.5 to 3.5 seconds.

Everything was great until a user try to navigate to different parts of the iPhora interface. Our iPhora SPA framework relies heavily on Dojo Require to dynamically load different parts of the UI. These modules may or may not exist when a bundle is created. In fact, for each instance the modules are totally different. So we went deep dive into the Dojo code and the dojo-webpack code and attempted many hacks.  After many many tries, I was informed that one cannot dynamically load AMD (Asynchronous Module Definition) modules when bundling with the dojo-webpack plugin. Unfortunately, Webpack replaces all Dojo Require with their own Webpack require which only allow static modules. So frustrating.

Since Webpack does not address our requirements. We looked at newer bundlers like Vite and Pascal, but that was going to require a significant effort since no one has a Dojo plug-in. The biggest struggle was finding examples and answers to questions.

Since the Dojo Toolkit comes with a bundler, we went back to looking at it. However, much of the documentation and examples are very simple as usual and limited. Much of the content was older and incomplete.

The advantage of the Dojo Build framework is that it allows you to create independent bundles called layers which conforms to how we are using Require to load the AMD modules. It uses the Google Closure compiler which is much more restrictive than Uglify-ES or Terser (used in webpack). We have been using Uglify-ES and then later Terser for a long time, but Closure does a better job in finding errors.

With Dojo Build we are able to build a custom dojo bundle that includes only the dojo modules that we needed and the individual modules that contain our initial loader and custom iPhora widgets.

So here are the results.

Before Using Dojo Build Bundling


After Using Dojo Build Bundling


As you can see the load time drops from 4.40 seconds to 2.62 seconds.  But more importantly is the reduction of HTTP request from 60 to 19.  Why 19?  One request is a cached request as a results of embedding an base64 image directly into the HTML page rather than requiring a http request.

As a result, you have better performance and able to handle more users per server instance. 

I hope this post was informative especially for the HCL community since a number of products still use the Dojo Toolkit framework and as well as many products from other companies.

For us, the next step is to include the new Dojo Build process into our DevOps process flow and run it automatically as we create new updates.

Listed below are links that might be of interest to you to learn more.  If you are attending Engage 2025 next month and have questions, track me down.  And if you are interested in data visualization, attend my session on Wednesday at 2:30 PM at the The Hague Conference Centre New Babylon, The Hauge, Netherlands.













Comments

Popular posts from this blog

Creating Twitter Bootstrap Widgets - Part II - Let's Assemble

MWLUG 2015 Session Abstract Submission is Now Open and New MWLUG 2015 Web site

The iPhora Journey - Part 8 - Flow-based Programming