Script Manager

The script manager is a means to dynamically load JavaScript resources bundled in one request and store the scripts in the local storage (if available). On subsequent pages the scripts are loaded from the local storage so that no additional requests are necessary.

The optimization at this time is mostly an HTTP 1.1 transport optimization. The Script Manager will be deactivated automatically when the Delivery Context Property request/http2 is set, because the measures taken can be counterproductive in HTTP 2.

If the client does not support local storage (or it is disabled), the script manager will store the scripts in the client’s JavaScript memory. This way, the scripts will have to be loaded again on every page load, but still only use one request. With partial page loading, the script manager does not need to reload the scripts on navigation, because the scripts stay in the memory of the client.

The execution order of the scripts is maintained. All user scripts delivered via the script manager are processed by the text filter and minified. The filtering and minification are done even if they are not activated in the config. The flow will not be used to process the scripts delivered by the script manager.

A tag is generated for every script. This tag is used by the script manager to determine if the saved script on the client is up to date or if a new version has to be requested. The tag contains a hash of the script and the client info that is used for the text filter processing. That way, if the source script or the client capabilities change, the script manager will request the correct version of the script.

Don’t use the script manager for scripts that use the text filter with request/* properties. These properties can change with every request. The scripts however are saved on the client and are not filtered with the new request properties.

Instead of using text filter for request properties, you can use the JavaScript Delivery Context API, or you can disable the script manager for the script by using the ai-use-script-manager attribute.

Configuration

Enable in conf/config.xml:

<config>
  <acceleration>
    <script-manager />
  </acceleration>
</config>

With the script manager enabled, all applicable scripts are automatically processed by the script manager.

Applicable Scripts

For a script to be loaded via script manager, it has to either be stored on the FIT server (e.g. an Adaptive Component script, or a script in the site/public folder), or the ACL has to allow its loading.

Only Scripts that are already in the FIT cache will be loaded via script manager. Scripts that are not already in the FIT cache will be loaded without script manager. On subsequent requests, the script will be present in the cache and can be loaded by the script manager.

Scripts with async or defer attribute are not loaded by the script manager.

FIT scripts use the script manager as well as long as they are not needed for the initialization of the script manager or are loaded with the async attribute.

ai-use-script-manager attribute

To exclude scripts from using the script manager, you can use the ai-use-script-manager="false" attribute. Using ai-use-script-manager="true" will not force scripts to be included that don’t match the above criteria.

Examples

<!-- this local script uses the script manager -->
<script id="foo" src="fit://site/public/js/foo.js"></script>

<!-- this ac-script uses the script manager -->
<script id="ac-example" src="fit://extension/ac-example/public/js/example.js"></script>

<!-- this script with ai-use-script-manager does not use the script manager -->
<script id="bar" src="fit://site/public/js/bar.js" ai-use-script-manager="false"></script>

<!-- this script from an external server does not use the script manager -->
<script id="extScript" src="http://example.com/script.js"></script>

<!-- this script with async attribute does not use the script manager -->
<script id="asyncScript" src="fit://site/public/js/asyncScript.js" async></script>

Script Manager Requests

When the script manager is used, all applicable scripts will be loaded in a single request. A script with the id AI_SCRIPT__loadJS_request is generated and inserted into the document. This script is responsible for loading all scripts that are not already loaded in the local storage (or memory if local storage is not available) or have a mismatching tag.

Additional scripts will be added to the document to insert the loaded scripts at the appropriate places into the document. The scripts have ids like AI_SCRIPT__loadJS_0 with a consecutive number.

The script manager will create a script element for each loaded script. The script content however will not be inserted into the document. Instead it is executed by the script manager.

The scripts will be requested via POST, with a blocking AJAX request. The blocking of the request is neccessary to ensure no script is executed before all prerequisite scripts are loaded.

The request is identified by the ;jsl URL Mark. The URLs of the requested scripts are sent as the parameters of the POST request. The scripts are referenced by their FIDJ URI (for example fit://site/public/js/script.js).

The response to the POST request contains all scripts wrapped into separate function calls of ai.sl.setResourceContent(). This function adds the loaded script to the local storage (if available, otherwise only to memory) with the matching URI to identify it and the tag to check for changes.

If a remote script file cannot be loaded (for example because of a server error or a timeout), the response will have the status code 500. The scripts that could be loaded will be inserted like usual.

If debugging is enabled, the script manager will generate a <script> tag for every script loaded. This script tag contains a data-src attribute showing the URL of the loaded Script.