Blazingly Fast Load Times For Apps Built with Ext JS and Sencha Touch

Blazingly Fast Load Times For Apps Built with Ext JS and Sencha TouchFor years, web developers have deployed their web applications according to the best practices defined by Yahoo’s Exceptional Performance team. Because traditional applications culminate in a vast collection of JavaScript source files, CSS stylesheets, and image artifacts, the best practices mandate the collective compression of these assets into single file downloads. In theory, delivering a single JavaScript file and a single CSS file reduces the overall number of HTTP requests (as well as reduces total asset size) resulting in optimal transmission and improved page initialization times.

Although there are a variety of publicly available tools to accomplish these basic tasks, none offers the convenience, dependency management, and build automation capabilities of Sencha Cmd for applications built with Ext JS and Sencha Touch. By simply running sencha app build, you only deploy the subset of the framework code that you actually need. When combined with your application code, the output is an optimized production build.

Typically small to medium size applications benefit the most from this build and deployment strategy, but the enterprise developer often must consider additional assembly factors. For example:

  • Enterprise desktop applications frequently involve hundreds of input forms and other complex presentation layouts. If incredibly large enterprise applications can exceed 8MB of JavaScript, CSS and images, does compressing everything into a single file really make a difference?
  • Role-based applications also present interesting engineering problems. Consider a “low level” user might only have 10% of functionality available to them — why should they download the other 90% of the code? Should the enterprise even risk serving them the compressed code for which they don’t have access privileges?

Clearly, the best practices surrounding this approach to minification plateau when applications get sufficiently large and/or complicated. Page initialization begins degrading at this scale because simply loading and parsing this much JavaScript (without even executing it) can freeze the browser.

There was no immediate solution to this problem, so the Sencha Professional Services team recently developed an approach that helped one of our customers. While it doesn’t solve every problem faced when building large enterprise applications, we wanted to share this solution, which leverages Sencha Cmd to dynamically load JavaScript resources on-demand.

You can view the project files used in this article on GitHub.

Wait – Isn’t Dynamic JS Loading Slow?

It can be — it depends on a few factors. Looking back at those best practices defined by Yahoo, the overall point is that reducing HTTP requests should decrease page loading times because most browsers have a default limit on the number of concurrent HTTP connections per domain (typically six). So, while in theory this means a single file would download faster than ten, it doesn’t necessarily mean a single large file will download faster than six smaller files in parallel.

First, we should consider that Ext JS and Sencha Touch applications built with Sencha Cmd have two environments: “development” and “production”. Sencha apps in “development” mode load each individual class based on their dependency chains (through the “requires” configuration), whereas apps in “production” mode would load a single “my-app-all.js” file containing only the necessary dependencies.

The approach we examined to dynamically load JavaScript code in production combines the idea of serving compressed “builds” (from “production” mode) with the flexibility of individual class loading (from “development” mode). Ultimately, we’re trying to improve the time it takes for an application to load, because application “speed” is all about the perception that the user does not wait for the UI.

Proposed Solution: Reduce JS File on Initial Load

Proposed Solution: Reduce JS File on Initial Load

Consider the above diagram. In a large enterprise application, only a fraction of the total code base is displayed or used on the initial screen. To achieve the best initial page load performance, it would be ideal to deliver only the code that’s needed for the initial screen. As long as the application loads quickly and the users are happy, we can selectively choose how and when to request other parts of the code base to access subsequent functionality.

Our approach to solving this problem was solely focused on improving the initial load time for a customer application — it’s important to note that this approach was specifically tailored to this specific situation and may not fit all scenarios. We did not tackle ideas surrounding selective CSS deployment, lazy-initializing controllers, or asynchronous loading mechanisms.

But, before we dive into the details of our approach, let’s first reiterate where this technique is appropriate:

  • Achieving faster load times for the initial “front page” view.
    • Has biggest impact in low power mobile devices (e.g. Android 2.x).
    • Improves initial and subsequent “front page” view load times; both benefit from parsing less JS code, and subsequent loads typically come from the cache (if set up properly).
  • Serving up JS code selectively
    • Supports security-focused policies of not serving code to users who don’t have permissions to run it anyway.
    • Appropriate for very large (3MB+) applications where only a small portion of the code base would get used in a given user session.

Sample App Setup

You can view the project files used in this article on GitHub.

Using Sencha Cmd, you can issue a basic “sencha generate app” command for Sencha Touch 2.3.1 apps which produces a basic project with a 2-tab tab panel. Let’s call it “ChunkCompile”. For this example, we will modify the second tab, so it contains a List and a custom component whose definitions will be downloaded only after the user navigates to the second tab.

In

Note that the second item is merely a Container with a TitleBar. This functions as a placeholder for “Page 2” in the following sequence:

  1. Intercept “Tab Change” event for the second tab.
  2. Download JavaScript content needed for Page 2.
  3. Add xtype “page2” into the second tab (we’ll define this view in a moment).

Loading JS & Views Dynamically

Pretend for a moment that we already have a “page2.js” file ready to go, compressed and containing only the code related to the “page2” widget. How would we load it dynamically and display the associated view?

Fortunately, we have the Ext.Loader.loadScriptFile() method. We will use this utility in