No announcement yet.
  • Filter
  • Time
Clear All
new posts

    Progressive/dynamic/on-demand javascript files loading

    We currently have a single page app that loads all the JavaScript content when index.html gets loaded (all the JS content is minified into a single file for network efficiency).

    We also use SmartClient's functionality that monitors HTTP 401 and challenges the user for username + password with a customized popup screen on timed out sessions.

    This means that when we deploy a new version of the app on the servers, logged in users can remain in the app and are NOT forced to a login window that will re-download all the latest-and-greatest JS content. They are "stuck" with JS content that might point to out-dated URLs or JS content that contains old business logic rules that have just been improved/fixed with the latest release).

    Another downside of that approach is that even if user A uses features 12 and 34 in the app, they download the JS needed to run features 1 to 50. This means that 90% percent of the JS they download at page load time will not be useful to them.

    We'd like to change this approach and use on-demand JS loading: user wants to go to feature 12, we download 12.js and is has the latest and greatest JS content to perform his operations (we'd actually use "12.js?appVersion=<major.minor.maintenance>" to decrease potential proxies/caching issues as we already do).

    I think this could be possible with the use of RequireJs (or any other tool) and a little rework on our side.

    Now, my question are:

    #1) Can RequireJs be used in a SmartClient context ? Any best practices ?

    #2) Does SmartClient have a built-in feature that dynamically loads JS, "evals" the downloaded JS to make it live (first taking time to unregister any content from previous version of "12.js" module) and process a callback or would we have to roll our own ?

    PS: On successful login, the back-end returns the current back-end version of the app in the login payload. We currently have logic in place that makes sure that the front-end has the same version in the downloaded JS content. When it's not the case, we issue a little popup to the user telling him that he has to log back in to get the latest and greatest. We basically boot them out and redirect them to index.html to get the latest JS content downloaded. The problem of the current approach (besides downloading features from 1 to 50 instead of dynamically loading 12 and 34 when needed) is that all the modules of the app are not aware of this login mechanism and we do not have a centralized way of dealing with it.

    Thanks !


    Read the SmartClient Architecture overview in the SmartClient Reference - it will explain why it does not make sense to load JS at the granularity you propose - that's actually much less efficient, and more complicated and error prone.

    As far as upgrades, it's unclear what you don't know how to handle: if you are trying to detect an active session with an older version, you can send the version with every call to the server. Just incorporate the version number into the RPCManager.actionURL.


      I looked at the Archiecture overview (SmartClient_v91p_2014-11-24_Pro/smartclientSDK/isomorphic/system/reference/SmartClient_Reference.html#group..smartArchitecture). Is it what you were referring to ? I didn't find the explanation you were mentionning... :-(

      Were you referring to FileLoader.loadJSFiles() ?


        The SmartClient Architecture overview basically points out that pre-loading dozens of views is what you want to do. To spell this out more fully: due to benefits of shared caching and the avoidance of additional network turnarounds, it is actually more efficient to go ahead and load JS that may not be used by a particular user, rather than try to load minimal sets. This is especially true since breaking up loading would require a bunch of API calls within your application to be converted from synchronous to asynchronous APIs, to accommodate the fact that the needed functionality might not be loaded yet.

        Generally, you should only consider breaking things into multiple separate JS loads when *all* of the following are true:

        1. the size of the functionality that you could avoid loading exceeds around 250-350k compressed
        2. your end users are neatly segmented such that certain classes of users almost never use certain features
        3. you've got actual concrete complaints about real-world load times that can't be addressed any other way
        4. there are few if any inter-module calls that would need to be made asynchronous, so little complexity will be added

        When *all* of the above are true, you *may* have a situation where splitting loading is a viable optimization - and even then, it probably has far less of an impact on actual performance than other optimizations that are easier to do.

        As a word of warning, we've seen a lot of teams get excited about implementing minimal loading, only to achieve no benefit (or worsen performance) after introducing a large amount of complexity.